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),
375b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong      mPrevBandwidthMeasureTimeUs(0),
385b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong      mPrevEstimatedBandWidthKbps(0),
39a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd      mBandWidthCollectFreqMs(5000),
40a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd      mMaxBandwidthHistoryItems(100) {
41b7319a7eb0a06ef4fd3a0c9157ee63e637ad7aa1Andreas Huber}
42b7319a7eb0a06ef4fd3a0c9157ee63e637ad7aa1Andreas Huber
435b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongvoid HTTPBase::addBandwidthMeasurement(
445b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        size_t numBytes, int64_t delayUs) {
455b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    Mutex::Autolock autoLock(mLock);
465b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
475b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    BandwidthEntry entry;
485b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    entry.mDelayUs = delayUs;
495b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    entry.mNumBytes = numBytes;
505b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    mTotalTransferTimeUs += delayUs;
515b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    mTotalTransferBytes += numBytes;
525b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
535b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    mBandwidthHistory.push_back(entry);
54a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd    if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {
555b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        BandwidthEntry *entry = &*mBandwidthHistory.begin();
565b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        mTotalTransferTimeUs -= entry->mDelayUs;
575b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        mTotalTransferBytes -= entry->mNumBytes;
585b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        mBandwidthHistory.erase(mBandwidthHistory.begin());
595b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        --mNumBandwidthHistoryItems;
605b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
615b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        int64_t timeNowUs = ALooper::GetNowUs();
625b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        if (timeNowUs - mPrevBandwidthMeasureTimeUs >=
635b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                mBandWidthCollectFreqMs * 1000LL) {
645b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
655b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            if (mPrevBandwidthMeasureTimeUs != 0) {
665b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                mPrevEstimatedBandWidthKbps =
675b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                    (mTotalTransferBytes * 8E3 / mTotalTransferTimeUs);
685b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            }
695b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            mPrevBandwidthMeasureTimeUs = timeNowUs;
705b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        }
715b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
725b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
735b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
745b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
755b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongbool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) {
765b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    Mutex::Autolock autoLock(mLock);
775b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
785b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    if (mNumBandwidthHistoryItems < 2) {
795b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        return false;
805b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
815b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
825b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
835b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
845b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    return true;
855b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
865b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
875b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) {
885b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    Mutex::Autolock autoLock(mLock);
895b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    *kbps = mPrevEstimatedBandWidthKbps;
905b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    return OK;
915b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
925b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
935b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {
945b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    Mutex::Autolock autoLock(mLock);
955b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
965b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    if (freqMs < kMinBandwidthCollectFreqMs
975b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            || freqMs > kMaxBandwidthCollectFreqMs) {
985b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
9929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("frequency (%d ms) is out of range [1000, 60000]", freqMs);
1005b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        return BAD_VALUE;
1015b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
1025b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
103df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("frequency set to %d ms", freqMs);
1045b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    mBandWidthCollectFreqMs = freqMs;
1055b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    return OK;
1065b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
1075b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
108a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowdvoid HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) {
109a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd    mMaxBandwidthHistoryItems = numHistoryItems;
110a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd}
111a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd
112dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber// static
113a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharmavoid HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
114a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    int res = qtaguid_tagSocket(sockfd, kTag, uid);
115a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    if (res != 0) {
11629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed tagging socket %d for uid %d (My UID=%d)", sockfd, uid, geteuid());
117a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    }
118a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma}
119a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma
120a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma// static
121a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharmavoid HTTPBase::UnRegisterSocketUserTag(int sockfd) {
122a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    int res = qtaguid_untagSocket(sockfd);
123a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    if (res != 0) {
12429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed untagging socket %d (My UID=%d)", sockfd, geteuid());
125a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma    }
126dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber}
127dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber
1285908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker// static
1295908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubakervoid HTTPBase::RegisterSocketUserMark(int sockfd, uid_t uid) {
1308e6912423c3be3fc2f4bab8ac815f0dce075ded8Sreeram Ramachandran    setNetworkForUser(uid, sockfd);
1315908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker}
1325908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker
1335908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker// static
1345908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubakervoid HTTPBase::UnRegisterSocketUserMark(int sockfd) {
1355908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker    RegisterSocketUserMark(sockfd, geteuid());
1365908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker}
1375908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker
1381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}  // namespace android
139