NuCachedSource2.cpp revision a7607a7f97b3136d5e61c0bca63760bf9fc05b19
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); 2165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->start(); 2175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 2195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(); 2205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2225994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::~NuCachedSource2() { 2235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->stop(); 2245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->unregisterHandler(mReflector->id()); 2255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete mCache; 2275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache = NULL; 2285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2305b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) { 231b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 232b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase* source = static_cast<HTTPBase *>(mSource.get()); 233b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->getEstimatedBandwidthKbps(kbps); 234b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 235b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2365b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2375b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2385b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) { 239b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 240b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase *source = static_cast<HTTPBase *>(mSource.get()); 241b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->setBandwidthStatCollectFreq(freqMs); 242b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 243b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2445b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2455b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstatus_t NuCachedSource2::initCheck() const { 2475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->initCheck(); 2485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 250c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::getSize(off64_t *size) { 2515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->getSize(size); 2525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberuint32_t NuCachedSource2::flags() { 255b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong // Remove HTTP related flags since NuCachedSource2 is not HTTP-based. 256b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource); 257b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return (flags | kIsCachingDataSource); 2585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2605994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) { 2615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber switch (msg->what()) { 2625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatFetchMore: 2635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onFetch(); 2655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatRead: 2695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onRead(msg); 2715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber default: 2755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber TRESPASS(); 2765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2795994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::fetchInternal() { 2803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("fetchInternal"); 2815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 28295c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber bool reconnect = false; 28395c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 2840683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber { 2850683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber Mutex::Autolock autoLock(mLock); 2860683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber CHECK(mFinalStatus == OK || mNumRetriesLeft > 0); 2870683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2880683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 2890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber --mNumRetriesLeft; 2900683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 29195c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber reconnect = true; 29295c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 29395c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 29495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 29595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber if (reconnect) { 29695c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber status_t err = 29795c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize()); 29895c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 29995c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber Mutex::Autolock autoLock(mLock); 3000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 301a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber if (err == ERROR_UNSUPPORTED || err == -EPIPE) { 302a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 303a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 30495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft = 0; 30595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 30695c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } else if (err != OK) { 307df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("The attempt to reconnect failed, %d retries remaining", 30895c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft); 3090683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 31095c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 3110683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3120683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache::Page *page = mCache->acquirePage(); 3155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t n = mSource->readAt( 3175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset + mCache->totalSize(), page->mData, kPageSize); 3185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 3205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (n < 0) { 3225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = n; 323a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber if (n == ERROR_UNSUPPORTED || n == -EPIPE) { 324a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 325a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 326a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber mNumRetriesLeft = 0; 327a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber } 328a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber 329a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft); 3305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else if (n == 0) { 332df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("ERROR_END_OF_STREAM"); 3330683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3340683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 3355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = ERROR_END_OF_STREAM; 3360683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else { 3390683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 340df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("retrying a previously failed read succeeded."); 3410683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3420683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = kMaxNumRetries; 3430683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mFinalStatus = OK; 3440683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = n; 3465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->appendPage(page); 3475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3505994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onFetch() { 3513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onFetch"); 3525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3530683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft == 0) { 3543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EOS reached, done prefetching for now"); 3555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 358a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber bool keepAlive = 359a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber !mFetching 360a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && mFinalStatus == OK 361a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && mKeepAliveIntervalUs > 0 362a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && ALooper::GetNowUs() >= mLastFetchTimeUs + mKeepAliveIntervalUs; 363a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 364a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching || keepAlive) { 365a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (keepAlive) { 366df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Keep alive"); 367a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber } 368a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 3695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber fetchInternal(); 3705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 371a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mLastFetchTimeUs = ALooper::GetNowUs(); 372a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 373a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) { 374df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Cache full, done prefetching for now"); 3755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 37649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 37749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (mDisconnectAtHighwatermark 37849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber && (mSource->flags() & DataSource::kIsHTTPBasedSource)) { 3793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Disconnecting at high watermark"); 38049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber static_cast<HTTPBase *>(mSource.get())->disconnect(); 38140a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mFinalStatus = -EAGAIN; 38249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 3835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 384a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 385d17875a226491e3de60fa32d764a4cc92de7f949Andreas Huber Mutex::Autolock autoLock(mLock); 3865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber restartPrefetcherIfNecessary_l(); 3875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber int64_t delayUs; 3900683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching) { 3910683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 3920683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // We failed this time and will try again in 3 seconds. 3930683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 3000000ll; 3940683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3950683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 0; 3960683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3970683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3980683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 100000ll; 3990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 4010683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs); 4025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4045994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onRead(const sp<AMessage> &msg) { 4053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onRead"); 4065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int64_t offset; 4085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findInt64("offset", &offset)); 4095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *data; 4115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findPointer("data", &data)); 4125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t size; 4145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findSize("size", &size)); 4155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t result = readInternal(offset, data, size); 4175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result == -EAGAIN) { 4195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(50000); 4205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult = new AMessage; 4285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult->setInt32("result", result); 4295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.signal(); 4315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 43334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::restartPrefetcherIfNecessary_l( 4347bf8413f91fc072452f315a91618aeef2574d420Andreas Huber bool ignoreLowWaterThreshold, bool force) { 4356ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const size_t kGrayArea = 1024 * 1024; 4365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4370683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) { 4385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4417bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!ignoreLowWaterThreshold && !force 44234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber && mCacheOffset + mCache->totalSize() - mLastAccessPos 443a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber >= mLowwaterThresholdBytes) { 4445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t maxBytes = mLastAccessPos - mCacheOffset; 4485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4497bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!force) { 4507bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (maxBytes < kGrayArea) { 4517bf8413f91fc072452f315a91618aeef2574d420Andreas Huber return; 4527bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4537bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 4547bf8413f91fc072452f315a91618aeef2574d420Andreas Huber maxBytes -= kGrayArea; 4557bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t actualBytes = mCache->releaseFromStart(maxBytes); 4585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset += actualBytes; 4595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 460df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("restarting prefetcher, totalSize = %d", mCache->totalSize()); 4615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 4625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 464c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { 4655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoSerializer(mSerializer); 4665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("readAt offset %lld, size %d", offset, size); 4685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // If the request can be completely satisfied from the cache, do so. 4725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 4745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber && offset + size <= mCacheOffset + mCache->totalSize()) { 4755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 4765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 4775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + size; 4795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 4815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber sp<AMessage> msg = new AMessage(kWhatRead, mReflector->id()); 4845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setInt64("offset", offset); 4855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setPointer("data", data); 4865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setSize("size", size); 4875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(); 4905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (mAsyncResult == NULL) { 4925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.wait(mLock); 4935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int32_t result; 4965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult->findInt32("result", &result)); 4975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult.clear(); 4995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result > 0) { 5015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + result; 5025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return (ssize_t)result; 5055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5075994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t NuCachedSource2::cachedSize() { 5085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mCacheOffset + mCache->totalSize(); 5105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 512a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const { 5135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5141bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney return approxDataRemaining_l(finalStatus); 5155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 517a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const { 5181bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney *finalStatus = mFinalStatus; 5190683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 5200683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 5210683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // Pretend that everything is fine until we're out of retries. 5220683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber *finalStatus = OK; 5230683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 5240683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 525c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t lastBytePosCached = mCacheOffset + mCache->totalSize(); 5265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mLastAccessPos < lastBytePosCached) { 5275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return lastBytePosCached - mLastAccessPos; 5285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return 0; 5305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 532c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) { 533a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber CHECK_LE(size, (size_t)mHighwaterThresholdBytes); 5347bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("readInternal offset %lld size %d", offset, size); 5365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5397bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!mFetching) { 5407bf8413f91fc072452f315a91618aeef2574d420Andreas Huber mLastAccessPos = offset; 5417bf8413f91fc072452f315a91618aeef2574d420Andreas Huber restartPrefetcherIfNecessary_l( 5427bf8413f91fc072452f315a91618aeef2574d420Andreas Huber false, // ignoreLowWaterThreshold 5437bf8413f91fc072452f315a91618aeef2574d420Andreas Huber true); // force 5447bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 5457bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset < mCacheOffset 547c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong || offset >= (off64_t)(mCacheOffset + mCache->totalSize())) { 5486ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const off64_t kPadding = 256 * 1024; 5495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // In the presence of multiple decoded streams, once of them will 5515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // trigger this seek request, the other one will request data "nearby" 5525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // soon, adjust the seek position so that that subsequent request 5535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // does not trigger another seek. 554c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t seekOffset = (offset > kPadding) ? offset - kPadding : 0; 5555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber seekInternal_l(seekOffset); 5575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 5605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 56140a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney if (mFinalStatus != OK && mNumRetriesLeft == 0) { 5625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (delta >= mCache->totalSize()) { 5635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mFinalStatus; 5645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5666f5aae1bcba130d5b8092a19fca3627aa565df56Andreas Huber size_t avail = mCache->totalSize() - delta; 56767802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 56867802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber if (avail > size) { 56967802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber avail = size; 57067802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber } 57167802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 5725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, avail); 5735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return avail; 5755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset + size <= mCacheOffset + mCache->totalSize()) { 5785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 5795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 5815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("deferring read"); 5845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return -EAGAIN; 5865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 588c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::seekInternal_l(off64_t offset) { 5895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset; 5905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 592c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong && offset <= (off64_t)(mCacheOffset + mCache->totalSize())) { 5935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 5945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 596df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("new range: offset= %lld", offset); 5975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset = offset; 5995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize = mCache->totalSize(); 6015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize); 6025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 60340a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mNumRetriesLeft = kMaxNumRetries; 6045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 6055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 6075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 6085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 60934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::resumeFetchingIfNecessary() { 61034ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber Mutex::Autolock autoLock(mLock); 61134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 61234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); 61334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber} 61434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 6159d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongsp<DecryptHandle> NuCachedSource2::DrmInitialization(const char* mime) { 6169d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong return mSource->DrmInitialization(mime); 617b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 618b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 619b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangvoid NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { 620b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang mSource->getDrmInfo(handle, client); 621b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 622b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 623771b85d9245a24273497792a2515d88d31c99e1eGloria WangString8 NuCachedSource2::getUri() { 624771b85d9245a24273497792a2515d88d31c99e1eGloria Wang return mSource->getUri(); 625771b85d9245a24273497792a2515d88d31c99e1eGloria Wang} 626ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber 6276511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 NuCachedSource2::getMIMEType() const { 6286511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber return mSource->getMIMEType(); 6296511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber} 6306511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber 631a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromSystemProperty() { 632a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber char value[PROPERTY_VALUE_MAX]; 633a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (!property_get("media.stagefright.cache-params", value, NULL)) { 634a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 635a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 636a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 637a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromString(value); 638a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 639a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 640a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromString(const char *s) { 641a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber ssize_t lowwaterMarkKb, highwaterMarkKb; 6420b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber int keepAliveSecs; 643a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6440b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (sscanf(s, "%ld/%ld/%d", 6450b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber &lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) { 64629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to parse cache parameters from '%s'.", s); 647a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 648a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 649a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 650a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (lowwaterMarkKb >= 0) { 651a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = lowwaterMarkKb * 1024; 652a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 653a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 654a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 655a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 656a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (highwaterMarkKb >= 0) { 657a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = highwaterMarkKb * 1024; 658a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 659a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 660a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 661a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6620b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (mLowwaterThresholdBytes >= mHighwaterThresholdBytes) { 66329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Illegal low/highwater marks specified, reverting to defaults."); 6640b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 6650b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 6660b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 6670b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 6680b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 6690b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (keepAliveSecs >= 0) { 6700b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = keepAliveSecs * 1000000ll; 6710b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } else { 6720b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs; 6730b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 674a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("lowwater = %d bytes, highwater = %d bytes, keepalive = %lld us", 676a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes, 677a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes, 678a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mKeepAliveIntervalUs); 679a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 680a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 68149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber// static 68249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Hubervoid NuCachedSource2::RemoveCacheSpecificHeaders( 68349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber KeyedVector<String8, String8> *headers, 68449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8 *cacheConfig, 68549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber bool *disconnectAtHighwatermark) { 68649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = String8(); 68749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = false; 68849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 68949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (headers == NULL) { 69049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber return; 69149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 69249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 69349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber ssize_t index; 69449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) { 69549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = headers->valueAt(index); 69649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 69749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 69849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 6993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Using special cache config '%s'", cacheConfig->string()); 70049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 70149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 70249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey( 70349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8("x-disconnect-at-highwatermark"))) >= 0) { 70449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = true; 70549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 70649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Client requested disconnection at highwater mark"); 70849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 70949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber} 71049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} // namespace android 712