11156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber/* 21156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Copyright (C) 2011 The Android Open Source Project 31156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * 41156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * you may not use this file except in compliance with the License. 61156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * You may obtain a copy of the License at 71156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * 81156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * 101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Unless required by applicable law or agreed to in writing, software 111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * See the License for the specific language governing permissions and 141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * limitations under the License. 151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber */ 161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 175b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong//#define LOG_NDEBUG 0 185b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#define LOG_TAG "HTTPBase" 195b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#include <utils/Log.h> 205b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "include/HTTPBase.h" 221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 23dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber#include <media/stagefright/foundation/ADebug.h> 245b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#include <media/stagefright/foundation/ALooper.h> 25dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber 261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <cutils/properties.h> 27dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber#include <cutils/qtaguid.h> 281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 298e6912423c3be3fc2f4bab8ac815f0dce075ded8Sreeram Ramachandran#include <NetdClient.h> 305908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker 311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubernamespace android { 321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 335b1b8a93a07326f1cbc627f09e02988375189e0aJames DongHTTPBase::HTTPBase() 345b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong : mNumBandwidthHistoryItems(0), 355b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferTimeUs(0), 365b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferBytes(0), 37ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mMaxBandwidthHistoryItems(100), 385b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mPrevBandwidthMeasureTimeUs(0), 395b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mPrevEstimatedBandWidthKbps(0), 40ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mBandWidthCollectFreqMs(5000) { 4169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen mName = String8("HTTPBase(<disconnected>)"); 42b7319a7eb0a06ef4fd3a0c9157ee63e637ad7aa1Andreas Huber} 43b7319a7eb0a06ef4fd3a0c9157ee63e637ad7aa1Andreas Huber 445b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongvoid HTTPBase::addBandwidthMeasurement( 455b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong size_t numBytes, int64_t delayUs) { 465b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong Mutex::Autolock autoLock(mLock); 475b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 485b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong BandwidthEntry entry; 495b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong entry.mDelayUs = delayUs; 505b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong entry.mNumBytes = numBytes; 515b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferTimeUs += delayUs; 525b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferBytes += numBytes; 535b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 545b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mBandwidthHistory.push_back(entry); 55a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) { 565b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong BandwidthEntry *entry = &*mBandwidthHistory.begin(); 575b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferTimeUs -= entry->mDelayUs; 585b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mTotalTransferBytes -= entry->mNumBytes; 595b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mBandwidthHistory.erase(mBandwidthHistory.begin()); 605b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong --mNumBandwidthHistoryItems; 615b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 625b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong int64_t timeNowUs = ALooper::GetNowUs(); 635b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong if (timeNowUs - mPrevBandwidthMeasureTimeUs >= 645b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mBandWidthCollectFreqMs * 1000LL) { 655b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 665b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong if (mPrevBandwidthMeasureTimeUs != 0) { 675b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mPrevEstimatedBandWidthKbps = 685b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong (mTotalTransferBytes * 8E3 / mTotalTransferTimeUs); 695b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong } 705b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mPrevBandwidthMeasureTimeUs = timeNowUs; 715b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong } 725b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong } 735b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 745b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 755b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 765b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongbool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) { 775b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong Mutex::Autolock autoLock(mLock); 785b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 79358e71747a4707f9429b8565a05482c1f68d0ed3Chong Zhang // Do not do bandwidth estimation if we don't have enough samples, or 80358e71747a4707f9429b8565a05482c1f68d0ed3Chong Zhang // total bytes download are too small (<64K). 81358e71747a4707f9429b8565a05482c1f68d0ed3Chong Zhang // Bandwidth estimation from these samples can often shoot up and cause 82358e71747a4707f9429b8565a05482c1f68d0ed3Chong Zhang // unwanted bw adaption behaviors. 83358e71747a4707f9429b8565a05482c1f68d0ed3Chong Zhang if (mNumBandwidthHistoryItems < 2 || mTotalTransferBytes < 65536) { 845b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong return false; 855b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong } 865b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 875b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs); 885b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 895b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong return true; 905b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 915b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 925b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) { 935b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong Mutex::Autolock autoLock(mLock); 945b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong *kbps = mPrevEstimatedBandWidthKbps; 955b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong return OK; 965b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 975b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 985b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) { 995b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong Mutex::Autolock autoLock(mLock); 1005b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 1015b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong if (freqMs < kMinBandwidthCollectFreqMs 1025b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong || freqMs > kMaxBandwidthCollectFreqMs) { 1035b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 10429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("frequency (%d ms) is out of range [1000, 60000]", freqMs); 1055b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong return BAD_VALUE; 1065b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong } 1075b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 108df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("frequency set to %d ms", freqMs); 1095b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong mBandWidthCollectFreqMs = freqMs; 1105b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong return OK; 1115b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 1125b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 113a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowdvoid HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) { 114a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd mMaxBandwidthHistoryItems = numHistoryItems; 115a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd} 116a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd 117dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber// static 118a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharmavoid HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) { 119a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma int res = qtaguid_tagSocket(sockfd, kTag, uid); 120a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma if (res != 0) { 12129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed tagging socket %d for uid %d (My UID=%d)", sockfd, uid, geteuid()); 122a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma } 123a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma} 124a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma 125a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma// static 126a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharmavoid HTTPBase::UnRegisterSocketUserTag(int sockfd) { 127a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma int res = qtaguid_untagSocket(sockfd); 128a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma if (res != 0) { 12929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed untagging socket %d (My UID=%d)", sockfd, geteuid()); 130a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma } 131dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber} 132dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber 1335908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker// static 1345908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubakervoid HTTPBase::RegisterSocketUserMark(int sockfd, uid_t uid) { 1358e6912423c3be3fc2f4bab8ac815f0dce075ded8Sreeram Ramachandran setNetworkForUser(uid, sockfd); 1365908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker} 1375908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker 1385908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker// static 1395908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubakervoid HTTPBase::UnRegisterSocketUserMark(int sockfd) { 1405908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker RegisterSocketUserMark(sockfd, geteuid()); 1415908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker} 1425908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker 1431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber} // namespace android 144