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
HTTPBase()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
Create(uint32_t flags)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
UpdateProxyConfig(const char * host,int32_t port,const char * exclusionList)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
addBandwidthMeasurement(size_t numBytes,int64_t delayUs)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
estimateBandwidth(int32_t * bandwidth_bps)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
getEstimatedBandwidthKbps(int32_t * kbps)115 status_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) {
116 Mutex::Autolock autoLock(mLock);
117 *kbps = mPrevEstimatedBandWidthKbps;
118 return OK;
119 }
120
setBandwidthStatCollectFreq(int32_t freqMs)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
setUID(uid_t uid)136 void HTTPBase::setUID(uid_t uid) {
137 mUIDValid = true;
138 mUID = uid;
139 }
140
getUID(uid_t * uid) const141 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
RegisterSocketUserTag(int sockfd,uid_t uid,uint32_t kTag)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
UnRegisterSocketUserTag(int sockfd)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