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 33 namespace android { 34 35 HTTPBase::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 47 sp<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 62 status_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 71 void 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 103 bool 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 115 status_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) { 116 Mutex::Autolock autoLock(mLock); 117 *kbps = mPrevEstimatedBandWidthKbps; 118 return OK; 119 } 120 121 status_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 136 void HTTPBase::setUID(uid_t uid) { 137 mUIDValid = true; 138 mUID = uid; 139 } 140 141 bool 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 152 void 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 160 void 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