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