NuCachedSource2.cpp revision 1b86fe063badb5f28c467ade39be0f4008688947
15994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber/* 25994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Copyright (C) 2010 The Android Open Source Project 35994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 45994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * you may not use this file except in compliance with the License. 65994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * You may obtain a copy of the License at 75994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 85994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Unless required by applicable law or agreed to in writing, software 115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * See the License for the specific language governing permissions and 145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * limitations under the License. 155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber */ 165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 17ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber//#define LOG_NDEBUG 0 185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#define LOG_TAG "NuCachedSource2" 195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <utils/Log.h> 205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include "include/NuCachedSource2.h" 225b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#include "include/HTTPBase.h" 235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 24a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber#include <cutils/properties.h> 255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/ADebug.h> 265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/AMessage.h> 275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/MediaErrors.h> 285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 295994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubernamespace android { 305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct PageCache { 325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache(size_t pageSize); 335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ~PageCache(); 345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber struct Page { 365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *mData; 375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mSize; 385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber }; 395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *acquirePage(); 415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void releasePage(Page *page); 425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void appendPage(Page *page); 445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t releaseFromStart(size_t maxBytes); 455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize() const { 475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mTotalSize; 485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void copy(size_t from, void *data, size_t size); 515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprivate: 535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mPageSize; 545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mTotalSize; 555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mActivePages; 575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mFreePages; 585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void freePages(List<Page *> *list); 605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(PageCache); 625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber}; 635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 645994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::PageCache(size_t pageSize) 655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mPageSize(pageSize), 665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize(0) { 675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 695994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::~PageCache() { 705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mActivePages); 715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mFreePages); 725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 745994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::freePages(List<Page *> *list) { 755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = list->begin(); 765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (it != list->end()) { 775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber free(page->mData); 805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete page; 815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page = NULL; 825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 875994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::Page *PageCache::acquirePage() { 885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (!mFreePages.empty()) { 895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mFreePages.begin(); 905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.erase(it); 925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = new Page; 975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mData = malloc(mPageSize); 985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 1015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1035994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::releasePage(Page *page) { 1045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 1055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.push_back(page); 1065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1085994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::appendPage(Page *page) { 1095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize += page->mSize; 1105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.push_back(page); 1115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1135994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t PageCache::releaseFromStart(size_t maxBytes) { 1145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t bytesReleased = 0; 1155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (maxBytes > 0 && !mActivePages.empty()) { 1175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 1205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (maxBytes < page->mSize) { 1225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 1235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.erase(it); 1265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber maxBytes -= page->mSize; 1285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber bytesReleased += page->mSize; 1295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber releasePage(page); 1315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize -= bytesReleased; 1345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return bytesReleased; 1355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1375994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::copy(size_t from, void *data, size_t size) { 1383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("copy from %d size %d", from, size); 1395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 140310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber if (size == 0) { 141310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber return; 142310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber } 143310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber 1445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_LE(from + size, mTotalSize); 1455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t offset = 0; 1475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (from >= offset + (*it)->mSize) { 1495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber offset += (*it)->mSize; 1505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = from - offset; 1545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t avail = (*it)->mSize - delta; 1555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (avail >= size) { 1575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, size); 1585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 1595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, avail); 1625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + avail; 1645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= avail; 1655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (size > 0) { 1675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t copy = (*it)->mSize; 1685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (copy > size) { 1695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber copy = size; 1705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (*it)->mData, copy); 1725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + copy; 1735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= copy; 1745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 18049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas HuberNuCachedSource2::NuCachedSource2( 18149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber const sp<DataSource> &source, 18249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber const char *cacheConfig, 18349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber bool disconnectAtHighwatermark) 1845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mSource(source), 1855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mReflector(new AHandlerReflector<NuCachedSource2>(this)), 1865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper(new ALooper), 1875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache(new PageCache(kPageSize)), 1885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset(0), 1895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus(OK), 1905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos(0), 191a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mFetching(true), 1920683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mLastFetchTimeUs(-1), 193a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mNumRetriesLeft(kMaxNumRetries), 194a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes(kDefaultHighWaterThreshold), 195a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes(kDefaultLowWaterThreshold), 19649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs), 19749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mDisconnectAtHighwatermark(disconnectAtHighwatermark) { 19849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // We are NOT going to support disconnect-at-highwatermark indefinitely 19949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // and we are not guaranteeing support for client-specified cache 20049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // parameters. Both of these are temporary measures to solve a specific 20149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // problem that will be solved in a better way going forward. 20249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 203a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromSystemProperty(); 204a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 20549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (cacheConfig != NULL) { 20649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber updateCacheParamsFromString(cacheConfig); 20749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 20849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 20949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (mDisconnectAtHighwatermark) { 21049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // Makes no sense to disconnect and do keep-alives... 21149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mKeepAliveIntervalUs = 0; 21249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 21349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 214a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mLooper->setName("NuCachedSource2"); 2155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->registerHandler(mReflector); 2161b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 2171b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // Since it may not be obvious why our looper thread needs to be 2181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // able to call into java since it doesn't appear to do so at all... 2191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // IMediaHTTPConnection may be (and most likely is) implemented in JAVA 2201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // and a local JAVA IBinder will call directly into JNI methods. 2211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // So whenever we call DataSource::readAt it may end up in a call to 2221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // IMediaHTTPConnection::readAt and therefore call back into JAVA. 2231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLooper->start(false /* runOnCallingThread */, true /* canCallJava */); 2245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 2265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(); 2275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2295994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::~NuCachedSource2() { 2305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->stop(); 2315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->unregisterHandler(mReflector->id()); 2325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete mCache; 2345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache = NULL; 2355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2375b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) { 238b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 239b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase* source = static_cast<HTTPBase *>(mSource.get()); 240b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->getEstimatedBandwidthKbps(kbps); 241b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 242b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2435b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2445b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2455b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) { 246b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 247b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase *source = static_cast<HTTPBase *>(mSource.get()); 248b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->setBandwidthStatCollectFreq(freqMs); 249b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 250b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2515b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2525b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstatus_t NuCachedSource2::initCheck() const { 2545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->initCheck(); 2555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 257c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::getSize(off64_t *size) { 2585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->getSize(size); 2595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberuint32_t NuCachedSource2::flags() { 262b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong // Remove HTTP related flags since NuCachedSource2 is not HTTP-based. 263b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource); 264b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return (flags | kIsCachingDataSource); 2655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2675994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) { 2685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber switch (msg->what()) { 2695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatFetchMore: 2705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onFetch(); 2725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatRead: 2765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onRead(msg); 2785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber default: 2825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber TRESPASS(); 2835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2865994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::fetchInternal() { 2873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("fetchInternal"); 2885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 28995c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber bool reconnect = false; 29095c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 2910683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber { 2920683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber Mutex::Autolock autoLock(mLock); 2930683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber CHECK(mFinalStatus == OK || mNumRetriesLeft > 0); 2940683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2950683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 2960683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber --mNumRetriesLeft; 2970683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 29895c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber reconnect = true; 29995c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 30095c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 30195c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 30295c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber if (reconnect) { 30395c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber status_t err = 30495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize()); 30595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 30695c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber Mutex::Autolock autoLock(mLock); 3070683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 308a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber if (err == ERROR_UNSUPPORTED || err == -EPIPE) { 309a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 310a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 31195c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft = 0; 31295c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 31395c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } else if (err != OK) { 314df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("The attempt to reconnect failed, %d retries remaining", 31595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft); 3160683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 31795c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 3180683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3190683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache::Page *page = mCache->acquirePage(); 3225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t n = mSource->readAt( 3245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset + mCache->totalSize(), page->mData, kPageSize); 3255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 3275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (n < 0) { 3295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = n; 330a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber if (n == ERROR_UNSUPPORTED || n == -EPIPE) { 331a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 332a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 333a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber mNumRetriesLeft = 0; 334a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber } 335a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber 336a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft); 3375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else if (n == 0) { 339df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("ERROR_END_OF_STREAM"); 3400683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3410683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 3425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = ERROR_END_OF_STREAM; 3430683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else { 3460683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 347df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("retrying a previously failed read succeeded."); 3480683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3490683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = kMaxNumRetries; 3500683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mFinalStatus = OK; 3510683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = n; 3535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->appendPage(page); 3545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3575994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onFetch() { 3583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onFetch"); 3595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3600683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft == 0) { 3613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EOS reached, done prefetching for now"); 3625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 365a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber bool keepAlive = 366a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber !mFetching 367a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && mFinalStatus == OK 368a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && mKeepAliveIntervalUs > 0 369a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && ALooper::GetNowUs() >= mLastFetchTimeUs + mKeepAliveIntervalUs; 370a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 371a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching || keepAlive) { 372a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (keepAlive) { 373df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Keep alive"); 374a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber } 375a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 3765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber fetchInternal(); 3775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 378a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mLastFetchTimeUs = ALooper::GetNowUs(); 379a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 380a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) { 381df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Cache full, done prefetching for now"); 3825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 38349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 38449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (mDisconnectAtHighwatermark 38549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber && (mSource->flags() & DataSource::kIsHTTPBasedSource)) { 3863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Disconnecting at high watermark"); 38749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber static_cast<HTTPBase *>(mSource.get())->disconnect(); 38840a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mFinalStatus = -EAGAIN; 38949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 3905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 391a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 392d17875a226491e3de60fa32d764a4cc92de7f949Andreas Huber Mutex::Autolock autoLock(mLock); 3935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber restartPrefetcherIfNecessary_l(); 3945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3960683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber int64_t delayUs; 3970683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching) { 3980683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 3990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // We failed this time and will try again in 3 seconds. 4000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 3000000ll; 4010683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 4020683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 0; 4030683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4040683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 4050683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 100000ll; 4060683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4070683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 4080683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs); 4095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4115994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onRead(const sp<AMessage> &msg) { 4123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onRead"); 4135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int64_t offset; 4155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findInt64("offset", &offset)); 4165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *data; 4185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findPointer("data", &data)); 4195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t size; 4215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findSize("size", &size)); 4225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t result = readInternal(offset, data, size); 4245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result == -EAGAIN) { 4265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(50000); 4275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult = new AMessage; 4355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult->setInt32("result", result); 4365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.signal(); 4385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 44034ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::restartPrefetcherIfNecessary_l( 4417bf8413f91fc072452f315a91618aeef2574d420Andreas Huber bool ignoreLowWaterThreshold, bool force) { 4426ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const size_t kGrayArea = 1024 * 1024; 4435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4440683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) { 4455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4487bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!ignoreLowWaterThreshold && !force 44934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber && mCacheOffset + mCache->totalSize() - mLastAccessPos 450a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber >= mLowwaterThresholdBytes) { 4515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t maxBytes = mLastAccessPos - mCacheOffset; 4555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4567bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!force) { 4577bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (maxBytes < kGrayArea) { 4587bf8413f91fc072452f315a91618aeef2574d420Andreas Huber return; 4597bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4607bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 4617bf8413f91fc072452f315a91618aeef2574d420Andreas Huber maxBytes -= kGrayArea; 4627bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t actualBytes = mCache->releaseFromStart(maxBytes); 4655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset += actualBytes; 4665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 467df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("restarting prefetcher, totalSize = %d", mCache->totalSize()); 4685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 4695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 471c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { 4725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoSerializer(mSerializer); 4735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("readAt offset %lld, size %d", offset, size); 4755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // If the request can be completely satisfied from the cache, do so. 4795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 4815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber && offset + size <= mCacheOffset + mCache->totalSize()) { 4825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 4835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 4845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + size; 4865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 4885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber sp<AMessage> msg = new AMessage(kWhatRead, mReflector->id()); 4915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setInt64("offset", offset); 4925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setPointer("data", data); 4935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setSize("size", size); 4945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(); 4975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (mAsyncResult == NULL) { 4995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.wait(mLock); 5005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int32_t result; 5035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult->findInt32("result", &result)); 5045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult.clear(); 5065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result > 0) { 5085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + result; 5095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return (ssize_t)result; 5125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5145994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t NuCachedSource2::cachedSize() { 5155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mCacheOffset + mCache->totalSize(); 5175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 519a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const { 5205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5211bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney return approxDataRemaining_l(finalStatus); 5225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 524a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const { 5251bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney *finalStatus = mFinalStatus; 5260683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 5270683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 5280683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // Pretend that everything is fine until we're out of retries. 5290683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber *finalStatus = OK; 5300683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 5310683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 532c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t lastBytePosCached = mCacheOffset + mCache->totalSize(); 5335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mLastAccessPos < lastBytePosCached) { 5345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return lastBytePosCached - mLastAccessPos; 5355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return 0; 5375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 539c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) { 540a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber CHECK_LE(size, (size_t)mHighwaterThresholdBytes); 5417bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("readInternal offset %lld size %d", offset, size); 5435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5467bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!mFetching) { 5477bf8413f91fc072452f315a91618aeef2574d420Andreas Huber mLastAccessPos = offset; 5487bf8413f91fc072452f315a91618aeef2574d420Andreas Huber restartPrefetcherIfNecessary_l( 5497bf8413f91fc072452f315a91618aeef2574d420Andreas Huber false, // ignoreLowWaterThreshold 5507bf8413f91fc072452f315a91618aeef2574d420Andreas Huber true); // force 5517bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 5527bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset < mCacheOffset 554c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong || offset >= (off64_t)(mCacheOffset + mCache->totalSize())) { 5556ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const off64_t kPadding = 256 * 1024; 5565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // In the presence of multiple decoded streams, once of them will 5585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // trigger this seek request, the other one will request data "nearby" 5595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // soon, adjust the seek position so that that subsequent request 5605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // does not trigger another seek. 561c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t seekOffset = (offset > kPadding) ? offset - kPadding : 0; 5625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber seekInternal_l(seekOffset); 5645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 5675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 56840a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney if (mFinalStatus != OK && mNumRetriesLeft == 0) { 5695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (delta >= mCache->totalSize()) { 5705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mFinalStatus; 5715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5736f5aae1bcba130d5b8092a19fca3627aa565df56Andreas Huber size_t avail = mCache->totalSize() - delta; 57467802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 57567802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber if (avail > size) { 57667802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber avail = size; 57767802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber } 57867802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 5795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, avail); 5805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return avail; 5825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset + size <= mCacheOffset + mCache->totalSize()) { 5855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 5865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 5885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("deferring read"); 5915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return -EAGAIN; 5935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 595c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::seekInternal_l(off64_t offset) { 5965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset; 5975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 599c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong && offset <= (off64_t)(mCacheOffset + mCache->totalSize())) { 6005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 6015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 603df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("new range: offset= %lld", offset); 6045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset = offset; 6065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize = mCache->totalSize(); 6085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize); 6095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 61040a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mNumRetriesLeft = kMaxNumRetries; 6115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 6125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 6145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 6155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 61634ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::resumeFetchingIfNecessary() { 61734ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber Mutex::Autolock autoLock(mLock); 61834ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 61934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); 62034ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber} 62134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 6229d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongsp<DecryptHandle> NuCachedSource2::DrmInitialization(const char* mime) { 6239d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong return mSource->DrmInitialization(mime); 624b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 625b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 626b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangvoid NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { 627b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang mSource->getDrmInfo(handle, client); 628b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 629b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 630771b85d9245a24273497792a2515d88d31c99e1eGloria WangString8 NuCachedSource2::getUri() { 631771b85d9245a24273497792a2515d88d31c99e1eGloria Wang return mSource->getUri(); 632771b85d9245a24273497792a2515d88d31c99e1eGloria Wang} 633ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber 6346511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 NuCachedSource2::getMIMEType() const { 6356511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber return mSource->getMIMEType(); 6366511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber} 6376511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber 638a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromSystemProperty() { 639a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber char value[PROPERTY_VALUE_MAX]; 640a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (!property_get("media.stagefright.cache-params", value, NULL)) { 641a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 642a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 643a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 644a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromString(value); 645a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 646a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 647a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromString(const char *s) { 648a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber ssize_t lowwaterMarkKb, highwaterMarkKb; 6490b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber int keepAliveSecs; 650a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6510b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (sscanf(s, "%ld/%ld/%d", 6520b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber &lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) { 65329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to parse cache parameters from '%s'.", s); 654a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 655a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 656a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 657a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (lowwaterMarkKb >= 0) { 658a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = lowwaterMarkKb * 1024; 659a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 660a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 661a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 662a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 663a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (highwaterMarkKb >= 0) { 664a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = highwaterMarkKb * 1024; 665a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 666a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 667a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 668a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6690b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (mLowwaterThresholdBytes >= mHighwaterThresholdBytes) { 67029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Illegal low/highwater marks specified, reverting to defaults."); 6710b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 6720b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 6730b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 6740b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 6750b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 6760b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (keepAliveSecs >= 0) { 6770b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = keepAliveSecs * 1000000ll; 6780b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } else { 6790b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs; 6800b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 681a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("lowwater = %d bytes, highwater = %d bytes, keepalive = %lld us", 683a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes, 684a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes, 685a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mKeepAliveIntervalUs); 686a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 687a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 68849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber// static 68949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Hubervoid NuCachedSource2::RemoveCacheSpecificHeaders( 69049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber KeyedVector<String8, String8> *headers, 69149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8 *cacheConfig, 69249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber bool *disconnectAtHighwatermark) { 69349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = String8(); 69449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = false; 69549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 69649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (headers == NULL) { 69749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber return; 69849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 69949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 70049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber ssize_t index; 70149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) { 70249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = headers->valueAt(index); 70349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 70449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 70549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Using special cache config '%s'", cacheConfig->string()); 70749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 70849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 70949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey( 71049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8("x-disconnect-at-highwatermark"))) >= 0) { 71149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = true; 71249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 71349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Client requested disconnection at highwater mark"); 71549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 71649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber} 71749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} // namespace android 719