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 17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 19ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber//#define LOG_NDEBUG 0 205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#define LOG_TAG "NuCachedSource2" 215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <utils/Log.h> 225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include "include/NuCachedSource2.h" 245b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#include "include/HTTPBase.h" 255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 26a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber#include <cutils/properties.h> 275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/ADebug.h> 285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/AMessage.h> 295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/MediaErrors.h> 305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 315994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubernamespace android { 325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct PageCache { 34090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit PageCache(size_t pageSize); 355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ~PageCache(); 365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber struct Page { 385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *mData; 395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mSize; 405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber }; 415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *acquirePage(); 435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void releasePage(Page *page); 445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void appendPage(Page *page); 465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t releaseFromStart(size_t maxBytes); 475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize() const { 495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mTotalSize; 505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void copy(size_t from, void *data, size_t size); 535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprivate: 555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mPageSize; 565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mTotalSize; 575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mActivePages; 595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mFreePages; 605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void freePages(List<Page *> *list); 625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(PageCache); 645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber}; 655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 665994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::PageCache(size_t pageSize) 675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mPageSize(pageSize), 685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize(0) { 695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 715994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::~PageCache() { 725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mActivePages); 735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mFreePages); 745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 765994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::freePages(List<Page *> *list) { 775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = list->begin(); 785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (it != list->end()) { 795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber free(page->mData); 825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete page; 835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page = NULL; 845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 895994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::Page *PageCache::acquirePage() { 905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (!mFreePages.empty()) { 915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mFreePages.begin(); 925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.erase(it); 945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = new Page; 995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mData = malloc(mPageSize); 1005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 1015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 1035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1055994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::releasePage(Page *page) { 1065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 1075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.push_back(page); 1085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1105994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::appendPage(Page *page) { 1115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize += page->mSize; 1125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.push_back(page); 1135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1155994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t PageCache::releaseFromStart(size_t maxBytes) { 1165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t bytesReleased = 0; 1175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (maxBytes > 0 && !mActivePages.empty()) { 1195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 1225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (maxBytes < page->mSize) { 1245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 1255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.erase(it); 1285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber maxBytes -= page->mSize; 1305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber bytesReleased += page->mSize; 1315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber releasePage(page); 1335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize -= bytesReleased; 1365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return bytesReleased; 1375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1395994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::copy(size_t from, void *data, size_t size) { 140a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("copy from %zu size %zu", from, size); 1415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 142310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber if (size == 0) { 143310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber return; 144310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber } 145310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber 1465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_LE(from + size, mTotalSize); 1475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t offset = 0; 1495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (from >= offset + (*it)->mSize) { 1515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber offset += (*it)->mSize; 1525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = from - offset; 1565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t avail = (*it)->mSize - delta; 1575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (avail >= size) { 1595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, size); 1605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 1615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, avail); 1645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + avail; 1665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= avail; 1675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (size > 0) { 1695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t copy = (*it)->mSize; 1705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (copy > size) { 1715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber copy = size; 1725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (*it)->mData, copy); 1745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + copy; 1755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= copy; 1765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 18249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas HuberNuCachedSource2::NuCachedSource2( 18349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber const sp<DataSource> &source, 18449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber const char *cacheConfig, 18549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber bool disconnectAtHighwatermark) 1865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mSource(source), 1875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mReflector(new AHandlerReflector<NuCachedSource2>(this)), 1885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper(new ALooper), 1895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache(new PageCache(kPageSize)), 1905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset(0), 1915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus(OK), 1925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos(0), 193a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mFetching(true), 19448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang mDisconnecting(false), 1950683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mLastFetchTimeUs(-1), 196a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mNumRetriesLeft(kMaxNumRetries), 197a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes(kDefaultHighWaterThreshold), 198a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes(kDefaultLowWaterThreshold), 19949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs), 20049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mDisconnectAtHighwatermark(disconnectAtHighwatermark) { 20149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // We are NOT going to support disconnect-at-highwatermark indefinitely 20249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // and we are not guaranteeing support for client-specified cache 20349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // parameters. Both of these are temporary measures to solve a specific 20449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // problem that will be solved in a better way going forward. 20549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 206a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromSystemProperty(); 207a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 20849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (cacheConfig != NULL) { 20949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber updateCacheParamsFromString(cacheConfig); 21049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 21149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 21249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (mDisconnectAtHighwatermark) { 21349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber // Makes no sense to disconnect and do keep-alives... 21449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber mKeepAliveIntervalUs = 0; 21549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 21649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 217a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mLooper->setName("NuCachedSource2"); 2185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->registerHandler(mReflector); 2191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 2201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // Since it may not be obvious why our looper thread needs to be 2211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // able to call into java since it doesn't appear to do so at all... 2221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // IMediaHTTPConnection may be (and most likely is) implemented in JAVA 2231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // and a local JAVA IBinder will call directly into JNI methods. 2241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // So whenever we call DataSource::readAt it may end up in a call to 2251b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // IMediaHTTPConnection::readAt and therefore call back into JAVA. 2261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLooper->start(false /* runOnCallingThread */, true /* canCallJava */); 22769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen 22869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen mName = String8::format("NuCachedSource2(%s)", mSource->toString().string()); 2295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2315994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::~NuCachedSource2() { 2325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->stop(); 2335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->unregisterHandler(mReflector->id()); 2345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete mCache; 2365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache = NULL; 2375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 239316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim// static 240316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kimsp<NuCachedSource2> NuCachedSource2::Create( 241316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim const sp<DataSource> &source, 242316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim const char *cacheConfig, 243316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim bool disconnectAtHighwatermark) { 244316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim sp<NuCachedSource2> instance = new NuCachedSource2( 245316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim source, cacheConfig, disconnectAtHighwatermark); 246316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim Mutex::Autolock autoLock(instance->mLock); 247316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim (new AMessage(kWhatFetchMore, instance->mReflector))->post(); 248316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim return instance; 249316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim} 250316c3d929ffb004b0150d515e82aede02208ce97Wonsik Kim 2515b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) { 252b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 253b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase* source = static_cast<HTTPBase *>(mSource.get()); 254b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->getEstimatedBandwidthKbps(kbps); 255b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 256b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2575b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2585b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 25948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhangvoid NuCachedSource2::disconnect() { 26048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang if (mSource->flags() & kIsHTTPBasedSource) { 26148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang ALOGV("disconnecting HTTPBasedSource"); 26248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 26348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang { 26448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang Mutex::Autolock autoLock(mLock); 26548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang // set mDisconnecting to true, if a fetch returns after 26648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang // this, the source will be marked as EOS. 26748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang mDisconnecting = true; 2689f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang 2699f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang // explicitly signal mCondition so that the pending readAt() 2709f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang // will immediately return 2719f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang mCondition.signal(); 27248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang } 27348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 27448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang // explicitly disconnect from the source, to allow any 27548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang // pending reads to return more promptly 27648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang static_cast<HTTPBase *>(mSource.get())->disconnect(); 27748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang } 27848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang} 27948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 2805b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) { 281b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 282b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase *source = static_cast<HTTPBase *>(mSource.get()); 283b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->setBandwidthStatCollectFreq(freqMs); 284b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 285b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2865b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2875b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstatus_t NuCachedSource2::initCheck() const { 2895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->initCheck(); 2905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 292c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::getSize(off64_t *size) { 2935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->getSize(size); 2945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberuint32_t NuCachedSource2::flags() { 297b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong // Remove HTTP related flags since NuCachedSource2 is not HTTP-based. 298b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource); 299b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return (flags | kIsCachingDataSource); 3005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3025994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) { 3035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber switch (msg->what()) { 3045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatFetchMore: 3055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 3065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onFetch(); 3075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 3085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatRead: 3115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 3125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onRead(msg); 3135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 3145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber default: 3175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber TRESPASS(); 3185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3215994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::fetchInternal() { 3223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("fetchInternal"); 3235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 32495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber bool reconnect = false; 32595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 3260683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber { 3270683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber Mutex::Autolock autoLock(mLock); 3280683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber CHECK(mFinalStatus == OK || mNumRetriesLeft > 0); 3290683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3300683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 3310683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber --mNumRetriesLeft; 3320683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 33395c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber reconnect = true; 33495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 33595c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } 33695c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 33795c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber if (reconnect) { 33895c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber status_t err = 33995c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize()); 34095c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber 34195c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber Mutex::Autolock autoLock(mLock); 3420683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3439f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang if (mDisconnecting) { 3449f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang mNumRetriesLeft = 0; 3459f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang mFinalStatus = ERROR_END_OF_STREAM; 3469f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang return; 3479f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang } else if (err == ERROR_UNSUPPORTED || err == -EPIPE) { 348a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 349a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 35095c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft = 0; 35195c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 35295c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber } else if (err != OK) { 353df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("The attempt to reconnect failed, %d retries remaining", 35495c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber mNumRetriesLeft); 3550683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 35695c4d6034dc356f70c6293ea53d4858415b2d020Andreas Huber return; 3570683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3580683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache::Page *page = mCache->acquirePage(); 3615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t n = mSource->readAt( 3635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset + mCache->totalSize(), page->mData, kPageSize); 3645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 3665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 36748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang if (n == 0 || mDisconnecting) { 368efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGI("caching reached eos."); 36948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 37048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang mNumRetriesLeft = 0; 37148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang mFinalStatus = ERROR_END_OF_STREAM; 37248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 37348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang mCache->releasePage(page); 37448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang } else if (n < 0) { 3755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = n; 376a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber if (n == ERROR_UNSUPPORTED || n == -EPIPE) { 377a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // These are errors that are not likely to go away even if we 378a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber // retry, i.e. the server doesn't support range requests or similar. 379a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber mNumRetriesLeft = 0; 380a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber } 381a7607a7f97b3136d5e61c0bca63760bf9fc05b19Andreas Huber 382a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("source returned error %zd, %d retries left", n, mNumRetriesLeft); 3835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else { 3850683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 386df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("retrying a previously failed read succeeded."); 3870683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3880683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = kMaxNumRetries; 3890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mFinalStatus = OK; 3900683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = n; 3925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->appendPage(page); 3935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3965994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onFetch() { 3973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onFetch"); 3985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft == 0) { 4003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EOS reached, done prefetching for now"); 4015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 4025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 404a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber bool keepAlive = 405a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber !mFetching 406a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && mFinalStatus == OK 407a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && mKeepAliveIntervalUs > 0 408a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && ALooper::GetNowUs() >= mLastFetchTimeUs + mKeepAliveIntervalUs; 409a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 410a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching || keepAlive) { 411a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (keepAlive) { 412df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Keep alive"); 413a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber } 414a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 4155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber fetchInternal(); 4165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 417a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mLastFetchTimeUs = ALooper::GetNowUs(); 418a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 419a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) { 420df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Cache full, done prefetching for now"); 4215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 42249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 42349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (mDisconnectAtHighwatermark 42449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber && (mSource->flags() & DataSource::kIsHTTPBasedSource)) { 4253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Disconnecting at high watermark"); 42649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber static_cast<HTTPBase *>(mSource.get())->disconnect(); 42740a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mFinalStatus = -EAGAIN; 42849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 4295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 430a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 431d17875a226491e3de60fa32d764a4cc92de7f949Andreas Huber Mutex::Autolock autoLock(mLock); 4325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber restartPrefetcherIfNecessary_l(); 4335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4350683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber int64_t delayUs; 4360683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching) { 4370683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 4380683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // We failed this time and will try again in 3 seconds. 4390683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 3000000ll; 4400683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 4410683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 0; 4420683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4430683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 4440683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 100000ll; 4450683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4460683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 4471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatFetchMore, mReflector))->post(delayUs); 4485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4505994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onRead(const sp<AMessage> &msg) { 4513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onRead"); 4525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int64_t offset; 4545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findInt64("offset", &offset)); 4555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *data; 4575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findPointer("data", &data)); 4585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t size; 4605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findSize("size", &size)); 4615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t result = readInternal(offset, data, size); 4635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result == -EAGAIN) { 4655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(50000); 4665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4704f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih if (mDisconnecting) { 4714f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih mCondition.signal(); 4724f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih return; 4734f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih } 4745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult = new AMessage; 4785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult->setInt32("result", result); 4795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.signal(); 4815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 48334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::restartPrefetcherIfNecessary_l( 4847bf8413f91fc072452f315a91618aeef2574d420Andreas Huber bool ignoreLowWaterThreshold, bool force) { 4856ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const size_t kGrayArea = 1024 * 1024; 4865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4870683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) { 4885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4917bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!ignoreLowWaterThreshold && !force 49234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber && mCacheOffset + mCache->totalSize() - mLastAccessPos 493a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber >= mLowwaterThresholdBytes) { 4945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t maxBytes = mLastAccessPos - mCacheOffset; 4985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4997bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!force) { 5007bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (maxBytes < kGrayArea) { 5017bf8413f91fc072452f315a91618aeef2574d420Andreas Huber return; 5027bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 5037bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5047bf8413f91fc072452f315a91618aeef2574d420Andreas Huber maxBytes -= kGrayArea; 5057bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 5065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t actualBytes = mCache->releaseFromStart(maxBytes); 5085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset += actualBytes; 5095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 510a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGI("restarting prefetcher, totalSize = %zu", mCache->totalSize()); 5115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 5125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 514c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { 5155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoSerializer(mSerializer); 5165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 517ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("readAt offset %lld, size %zu", (long long)offset, size); 5185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5204f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih if (mDisconnecting) { 5214f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih return ERROR_END_OF_STREAM; 5224f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih } 5235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // If the request can be completely satisfied from the cache, do so. 5255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 5275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber && offset + size <= mCacheOffset + mCache->totalSize()) { 5285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 5295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 5305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + size; 5325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 5345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRead, mReflector); 5375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setInt64("offset", offset); 5385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setPointer("data", data); 5395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setSize("size", size); 5405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 5425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(); 5435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5449f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang while (mAsyncResult == NULL && !mDisconnecting) { 5455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.wait(mLock); 5465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5489f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang if (mDisconnecting) { 5494f17dadd3cfd9940893ea042ca8883c6aa6ada07Robert Shih mAsyncResult.clear(); 5509f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang return ERROR_END_OF_STREAM; 5519f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang } 5529f3d1cffe3bbec35c1fb7fc7e206428728ac234eChong Zhang 5535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int32_t result; 5545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult->findInt32("result", &result)); 5555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult.clear(); 5575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result > 0) { 5595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + result; 5605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return (ssize_t)result; 5635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5655994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t NuCachedSource2::cachedSize() { 5665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mCacheOffset + mCache->totalSize(); 5685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 570a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const { 5715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5721bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney return approxDataRemaining_l(finalStatus); 5735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 575a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubersize_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const { 5761bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney *finalStatus = mFinalStatus; 5770683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 5780683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 5790683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // Pretend that everything is fine until we're out of retries. 5800683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber *finalStatus = OK; 5810683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 5820683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 583c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t lastBytePosCached = mCacheOffset + mCache->totalSize(); 5845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mLastAccessPos < lastBytePosCached) { 5855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return lastBytePosCached - mLastAccessPos; 5865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return 0; 5885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 590c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) { 591a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber CHECK_LE(size, (size_t)mHighwaterThresholdBytes); 5927bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 593ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("readInternal offset %lld size %zu", (long long)offset, size); 5945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 5965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5972c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang // If we're disconnecting, return EOS and don't access *data pointer. 5982c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang // data could be on the stack of the caller to NuCachedSource2::readAt(), 5992c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang // which may have exited already. 6002c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang if (mDisconnecting) { 6012c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang return ERROR_END_OF_STREAM; 6022c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang } 6032c878cfdf36b896abb99e62a37188cc92cd4fe6eChong Zhang 6047bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!mFetching) { 6057bf8413f91fc072452f315a91618aeef2574d420Andreas Huber mLastAccessPos = offset; 6067bf8413f91fc072452f315a91618aeef2574d420Andreas Huber restartPrefetcherIfNecessary_l( 6077bf8413f91fc072452f315a91618aeef2574d420Andreas Huber false, // ignoreLowWaterThreshold 6087bf8413f91fc072452f315a91618aeef2574d420Andreas Huber true); // force 6097bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 6107bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 6115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset < mCacheOffset 612c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong || offset >= (off64_t)(mCacheOffset + mCache->totalSize())) { 6136ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const off64_t kPadding = 256 * 1024; 6145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // In the presence of multiple decoded streams, once of them will 6165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // trigger this seek request, the other one will request data "nearby" 6175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // soon, adjust the seek position so that that subsequent request 6185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // does not trigger another seek. 619c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t seekOffset = (offset > kPadding) ? offset - kPadding : 0; 6205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber seekInternal_l(seekOffset); 6225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 6255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 62640a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney if (mFinalStatus != OK && mNumRetriesLeft == 0) { 6275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (delta >= mCache->totalSize()) { 6285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mFinalStatus; 6295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6316f5aae1bcba130d5b8092a19fca3627aa565df56Andreas Huber size_t avail = mCache->totalSize() - delta; 63267802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 63367802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber if (avail > size) { 63467802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber avail = size; 63567802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber } 63667802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 6375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, avail); 6385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return avail; 6405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset + size <= mCacheOffset + mCache->totalSize()) { 6435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 6445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 6465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("deferring read"); 6495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return -EAGAIN; 6515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 6525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 653c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::seekInternal_l(off64_t offset) { 6545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset; 6555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 657c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong && offset <= (off64_t)(mCacheOffset + mCache->totalSize())) { 6585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 6595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 6605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 661ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGI("new range: offset= %lld", (long long)offset); 6625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset = offset; 6645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize = mCache->totalSize(); 6665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize); 6675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 66840a4e1440869b2e3981f261b0d301cd16c0cf0aaBryan Mawhinney mNumRetriesLeft = kMaxNumRetries; 6695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 6705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 6715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 6725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 6735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 67434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::resumeFetchingIfNecessary() { 67534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber Mutex::Autolock autoLock(mLock); 67634ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 67734ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); 67834ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber} 67934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 6809d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongsp<DecryptHandle> NuCachedSource2::DrmInitialization(const char* mime) { 6819d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong return mSource->DrmInitialization(mime); 682b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 683b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 684771b85d9245a24273497792a2515d88d31c99e1eGloria WangString8 NuCachedSource2::getUri() { 685771b85d9245a24273497792a2515d88d31c99e1eGloria Wang return mSource->getUri(); 686771b85d9245a24273497792a2515d88d31c99e1eGloria Wang} 687ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber 6886511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 NuCachedSource2::getMIMEType() const { 6896511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber return mSource->getMIMEType(); 6906511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber} 6916511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber 692a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromSystemProperty() { 693a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber char value[PROPERTY_VALUE_MAX]; 694a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (!property_get("media.stagefright.cache-params", value, NULL)) { 695a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 696a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 697a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 698a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromString(value); 699a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 700a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 701a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromString(const char *s) { 702a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber ssize_t lowwaterMarkKb, highwaterMarkKb; 7030b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber int keepAliveSecs; 704a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 705db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn if (sscanf(s, "%zd/%zd/%d", 7060b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber &lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) { 70729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to parse cache parameters from '%s'.", s); 708a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 709a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 710a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 711a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (lowwaterMarkKb >= 0) { 712a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = lowwaterMarkKb * 1024; 713a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 714a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 715a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 716a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 717a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (highwaterMarkKb >= 0) { 718a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = highwaterMarkKb * 1024; 719a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 720a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 721a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 722a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 7230b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (mLowwaterThresholdBytes >= mHighwaterThresholdBytes) { 72429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Illegal low/highwater marks specified, reverting to defaults."); 7250b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 7260b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 7270b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 7280b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 7290b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber 7300b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber if (keepAliveSecs >= 0) { 7310b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = keepAliveSecs * 1000000ll; 7320b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } else { 7330b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs; 7340b8cd8b0cf1489f8f7c0b2c4d7ea8fea70ca93a1Andreas Huber } 735a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 736ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("lowwater = %zu bytes, highwater = %zu bytes, keepalive = %lld us", 737a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes, 738a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes, 739ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar (long long)mKeepAliveIntervalUs); 740a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 741a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 74249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber// static 74349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Hubervoid NuCachedSource2::RemoveCacheSpecificHeaders( 74449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber KeyedVector<String8, String8> *headers, 74549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8 *cacheConfig, 74649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber bool *disconnectAtHighwatermark) { 74749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = String8(); 74849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = false; 74949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 75049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if (headers == NULL) { 75149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber return; 75249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 75349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 75449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber ssize_t index; 75549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) { 75649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *cacheConfig = headers->valueAt(index); 75749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 75849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 75949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Using special cache config '%s'", cacheConfig->string()); 76149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 76249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 76349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber if ((index = headers->indexOfKey( 76449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber String8("x-disconnect-at-highwatermark"))) >= 0) { 76549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber *disconnectAtHighwatermark = true; 76649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber headers->removeItemsAt(index); 76749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Client requested disconnection at highwater mark"); 76949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber } 77049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber} 77149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber 7725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} // namespace android 773