1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "HTTPBase" 19#include <utils/Log.h> 20 21#include "include/HTTPBase.h" 22 23#if CHROMIUM_AVAILABLE 24#include "include/chromium_http_stub.h" 25#endif 26 27#include <media/stagefright/foundation/ADebug.h> 28#include <media/stagefright/foundation/ALooper.h> 29 30#include <cutils/properties.h> 31#include <cutils/qtaguid.h> 32 33namespace android { 34 35HTTPBase::HTTPBase() 36 : mNumBandwidthHistoryItems(0), 37 mTotalTransferTimeUs(0), 38 mTotalTransferBytes(0), 39 mPrevBandwidthMeasureTimeUs(0), 40 mPrevEstimatedBandWidthKbps(0), 41 mBandWidthCollectFreqMs(5000), 42 mUIDValid(false), 43 mUID(0) { 44} 45 46// static 47sp<HTTPBase> HTTPBase::Create(uint32_t flags) { 48#if CHROMIUM_AVAILABLE 49 HTTPBase *dataSource = createChromiumHTTPDataSource(flags); 50 if (dataSource) { 51 return dataSource; 52 } 53#endif 54 { 55 TRESPASS(); 56 57 return NULL; 58 } 59} 60 61// static 62status_t HTTPBase::UpdateProxyConfig( 63 const char *host, int32_t port, const char *exclusionList) { 64#if CHROMIUM_AVAILABLE 65 return UpdateChromiumHTTPDataSourceProxyConfig(host, port, exclusionList); 66#else 67 return INVALID_OPERATION; 68#endif 69} 70 71void HTTPBase::addBandwidthMeasurement( 72 size_t numBytes, int64_t delayUs) { 73 Mutex::Autolock autoLock(mLock); 74 75 BandwidthEntry entry; 76 entry.mDelayUs = delayUs; 77 entry.mNumBytes = numBytes; 78 mTotalTransferTimeUs += delayUs; 79 mTotalTransferBytes += numBytes; 80 81 mBandwidthHistory.push_back(entry); 82 if (++mNumBandwidthHistoryItems > 100) { 83 BandwidthEntry *entry = &*mBandwidthHistory.begin(); 84 mTotalTransferTimeUs -= entry->mDelayUs; 85 mTotalTransferBytes -= entry->mNumBytes; 86 mBandwidthHistory.erase(mBandwidthHistory.begin()); 87 --mNumBandwidthHistoryItems; 88 89 int64_t timeNowUs = ALooper::GetNowUs(); 90 if (timeNowUs - mPrevBandwidthMeasureTimeUs >= 91 mBandWidthCollectFreqMs * 1000LL) { 92 93 if (mPrevBandwidthMeasureTimeUs != 0) { 94 mPrevEstimatedBandWidthKbps = 95 (mTotalTransferBytes * 8E3 / mTotalTransferTimeUs); 96 } 97 mPrevBandwidthMeasureTimeUs = timeNowUs; 98 } 99 } 100 101} 102 103bool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) { 104 Mutex::Autolock autoLock(mLock); 105 106 if (mNumBandwidthHistoryItems < 2) { 107 return false; 108 } 109 110 *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs); 111 112 return true; 113} 114 115status_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) { 116 Mutex::Autolock autoLock(mLock); 117 *kbps = mPrevEstimatedBandWidthKbps; 118 return OK; 119} 120 121status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) { 122 Mutex::Autolock autoLock(mLock); 123 124 if (freqMs < kMinBandwidthCollectFreqMs 125 || freqMs > kMaxBandwidthCollectFreqMs) { 126 127 ALOGE("frequency (%d ms) is out of range [1000, 60000]", freqMs); 128 return BAD_VALUE; 129 } 130 131 ALOGI("frequency set to %d ms", freqMs); 132 mBandWidthCollectFreqMs = freqMs; 133 return OK; 134} 135 136void HTTPBase::setUID(uid_t uid) { 137 mUIDValid = true; 138 mUID = uid; 139} 140 141bool HTTPBase::getUID(uid_t *uid) const { 142 if (!mUIDValid) { 143 return false; 144 } 145 146 *uid = mUID; 147 148 return true; 149} 150 151// static 152void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) { 153 int res = qtaguid_tagSocket(sockfd, kTag, uid); 154 if (res != 0) { 155 ALOGE("Failed tagging socket %d for uid %d (My UID=%d)", sockfd, uid, geteuid()); 156 } 157} 158 159// static 160void HTTPBase::UnRegisterSocketUserTag(int sockfd) { 161 int res = qtaguid_untagSocket(sockfd); 162 if (res != 0) { 163 ALOGE("Failed untagging socket %d (My UID=%d)", sockfd, geteuid()); 164 } 165} 166 167} // namespace android 168