From 9b80c2bdb205bc143104f54d0743b6eedd67b14e Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Thu, 30 Jun 2011 15:47:02 -0700 Subject: Charge network traffic to the uid of the process using the MediaPlayer. Change-Id: I2bcb54b8232afd3fc7ee16289f37c7a7b3f23067 related-to-bug: 4517282 --- media/libstagefright/AwesomePlayer.cpp | 16 ++++++++++++++++ media/libstagefright/HTTPBase.cpp | 18 +++++++++++++++++- media/libstagefright/HTTPStream.cpp | 23 +++++++++++++++++++++++ media/libstagefright/NuHTTPDataSource.cpp | 5 +++++ media/libstagefright/httplive/LiveSession.cpp | 11 ++++++++++- media/libstagefright/include/ARTSPController.h | 5 +++++ media/libstagefright/include/AwesomePlayer.h | 3 +++ media/libstagefright/include/HTTPBase.h | 6 +++++- media/libstagefright/include/HTTPStream.h | 8 ++++++++ media/libstagefright/include/LiveSession.h | 4 +++- media/libstagefright/rtsp/ARTSPConnection.cpp | 12 ++++++++++-- media/libstagefright/rtsp/ARTSPConnection.h | 4 +++- media/libstagefright/rtsp/ARTSPController.cpp | 8 +++++++- media/libstagefright/rtsp/MyHandler.h | 19 ++++++++++++++++--- 14 files changed, 131 insertions(+), 11 deletions(-) (limited to 'media/libstagefright') diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index aa7edcc..56b28a2 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -180,6 +180,7 @@ void addBatteryData(uint32_t params) { //////////////////////////////////////////////////////////////////////////////// AwesomePlayer::AwesomePlayer() : mQueueStarted(false), + mUIDValid(false), mTimeSource(NULL), mVideoRendererIsPreview(false), mAudioPlayer(NULL), @@ -243,6 +244,13 @@ void AwesomePlayer::setListener(const wp &listener) { mListener = listener; } +void AwesomePlayer::setUID(uid_t uid) { + LOGI("AwesomePlayer running on behalf of uid %d", uid); + + mUID = uid; + mUIDValid = true; +} + status_t AwesomePlayer::setDataSource( const char *uri, const KeyedVector *headers) { Mutex::Autolock autoLock(mLock); @@ -1928,6 +1936,10 @@ status_t AwesomePlayer::finishSetDataSource_l() { ? HTTPBase::kFlagIncognito : 0); + if (mUIDValid) { + mConnectingDataSource->setUID(mUID); + } + mLock.unlock(); status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders); mLock.lock(); @@ -2009,6 +2021,10 @@ status_t AwesomePlayer::finishSetDataSource_l() { mRTSPController = new ARTSPController(mLooper); mConnectingRTSPController = mRTSPController; + if (mUIDValid) { + mConnectingRTSPController->setUID(mUID); + } + mLock.unlock(); status_t err = mRTSPController->connect(mUri.string()); mLock.lock(); diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp index c0ae29d..0d24551 100644 --- a/media/libstagefright/HTTPBase.cpp +++ b/media/libstagefright/HTTPBase.cpp @@ -37,7 +37,8 @@ HTTPBase::HTTPBase() mTotalTransferBytes(0), mPrevBandwidthMeasureTimeUs(0), mPrevEstimatedBandWidthKbps(0), - mBandWidthCollectFreqMs(5000) { + mBandWidthCollectFreqMs(5000), + mUIDValid(false) { } // static @@ -119,4 +120,19 @@ status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) { return OK; } +void HTTPBase::setUID(uid_t uid) { + mUIDValid = true; + mUID = uid; +} + +bool HTTPBase::getUID(uid_t *uid) const { + if (!mUIDValid) { + return false; + } + + *uid = mUID; + + return true; +} + } // namespace android diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp index a156da6..d526ebd 100644 --- a/media/libstagefright/HTTPStream.cpp +++ b/media/libstagefright/HTTPStream.cpp @@ -43,6 +43,7 @@ const char *HTTPStream::kStatusKey = ":status:"; // MUST be lowercase. HTTPStream::HTTPStream() : mState(READY), + mUIDValid(false), mSocket(-1), mSSLContext(NULL), mSSL(NULL) { @@ -57,6 +58,11 @@ HTTPStream::~HTTPStream() { } } +void HTTPStream::setUID(uid_t uid) { + mUIDValid = true; + mUID = uid; +} + static bool MakeSocketBlocking(int s, bool blocking) { // Make socket non-blocking. int flags = fcntl(s, F_GETFL, 0); @@ -250,6 +256,10 @@ status_t HTTPStream::connect(const char *server, int port, bool https) { continue; } + if (mUIDValid) { + RegisterSocketUser(mSocket, mUID); + } + setReceiveTimeout(30); // Time out reads after 30 secs by default. int s = mSocket; @@ -596,5 +606,18 @@ void HTTPStream::setReceiveTimeout(int seconds) { CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))); } +// static +void HTTPStream::RegisterSocketUser(int s, uid_t uid) { + // Lower bits MUST be 0. + static const uint64_t kTag = 0xdeadbeef00000000ll; + + AString line = StringPrintf("t %d %llu %d", s, kTag, uid); + + int fd = open("/proc/net/xt_qtaguid/ctrl", O_WRONLY); + write(fd, line.c_str(), line.size()); + close(fd); + fd = -1; +} + } // namespace android diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp index dac2ee4..2949767 100644 --- a/media/libstagefright/NuHTTPDataSource.cpp +++ b/media/libstagefright/NuHTTPDataSource.cpp @@ -140,6 +140,11 @@ status_t NuHTTPDataSource::connect( return ERROR_MALFORMED; } + uid_t uid; + if (getUID(&uid)) { + mHTTP.setUID(uid); + } + return connect(host, port, path, https, headers, offset); } diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index f1a2a60..8ecc17c 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -41,8 +41,10 @@ namespace android { const int64_t LiveSession::kMaxPlaylistAgeUs = 15000000ll; -LiveSession::LiveSession(uint32_t flags) +LiveSession::LiveSession(uint32_t flags, bool uidValid, uid_t uid) : mFlags(flags), + mUIDValid(uidValid), + mUID(uid), mDataSource(new LiveDataSource), mHTTPDataSource( HTTPBase::Create( @@ -58,6 +60,9 @@ LiveSession::LiveSession(uint32_t flags) mSeekDone(false), mDisconnectPending(false), mMonitorQueueGeneration(0) { + if (mUIDValid) { + mHTTPDataSource->setUID(mUID); + } } LiveSession::~LiveSession() { @@ -671,6 +676,10 @@ status_t LiveSession::decryptBuffer( ? HTTPBase::kFlagIncognito : 0); + if (mUIDValid) { + keySource->setUID(mUID); + } + status_t err = keySource->connect(keyURI.c_str()); if (err == OK) { diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h index ce7ffe5..2bd5be6 100644 --- a/media/libstagefright/include/ARTSPController.h +++ b/media/libstagefright/include/ARTSPController.h @@ -30,6 +30,8 @@ struct MyHandler; struct ARTSPController : public MediaExtractor { ARTSPController(const sp &looper); + void setUID(uid_t uid); + status_t connect(const char *url); void disconnect(); @@ -80,6 +82,9 @@ private: sp mHandler; sp > mReflector; + bool mUIDValid; + uid_t mUID; + void (*mSeekDoneCb)(void *); void *mSeekDoneCookie; int64_t mLastSeekCompletedTimeUs; diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index f6df380..e069b4d 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -62,6 +62,7 @@ struct AwesomePlayer { ~AwesomePlayer(); void setListener(const wp &listener); + void setUID(uid_t uid); status_t setDataSource( const char *uri, @@ -150,6 +151,8 @@ private: TimedEventQueue mQueue; bool mQueueStarted; wp mListener; + bool mUIDValid; + uid_t mUID; sp mSurface; sp mNativeWindow; diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h index 3a7fbb6..2e25dd9 100644 --- a/media/libstagefright/include/HTTPBase.h +++ b/media/libstagefright/include/HTTPBase.h @@ -48,13 +48,15 @@ struct HTTPBase : public DataSource { virtual status_t setBandwidthStatCollectFreq(int32_t freqMs); + void setUID(uid_t uid); + bool getUID(uid_t *uid) const; + static sp Create(uint32_t flags = 0); protected: void addBandwidthMeasurement(size_t numBytes, int64_t delayUs); private: - struct BandwidthEntry { int64_t mDelayUs; size_t mNumBytes; @@ -76,6 +78,8 @@ private: int32_t mPrevEstimatedBandWidthKbps; int32_t mBandWidthCollectFreqMs; + bool mUIDValid; + uid_t mUID; DISALLOW_EVIL_CONSTRUCTORS(HTTPBase); }; diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h index 09e6a5f..88ba9d6 100644 --- a/media/libstagefright/include/HTTPStream.h +++ b/media/libstagefright/include/HTTPStream.h @@ -32,6 +32,8 @@ public: HTTPStream(); ~HTTPStream(); + void setUID(uid_t uid); + status_t connect(const char *server, int port = -1, bool https = false); status_t disconnect(); @@ -58,6 +60,8 @@ public: // _excluding_ the termianting CRLF. status_t receive_line(char *line, size_t size); + static void RegisterSocketUser(int s, uid_t uid); + private: enum State { READY, @@ -67,6 +71,10 @@ private: State mState; Mutex mLock; + + bool mUIDValid; + uid_t mUID; + int mSocket; KeyedVector mHeaders; diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h index 99abe64..188ef5e 100644 --- a/media/libstagefright/include/LiveSession.h +++ b/media/libstagefright/include/LiveSession.h @@ -35,7 +35,7 @@ struct LiveSession : public AHandler { // Don't log any URLs. kFlagIncognito = 1, }; - LiveSession(uint32_t flags = 0); + LiveSession(uint32_t flags = 0, bool uidValid = false, uid_t uid = 0); sp getDataSource(); @@ -77,6 +77,8 @@ private: }; uint32_t mFlags; + bool mUIDValid; + uid_t mUID; sp mDataSource; diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index c4e0cdc..072d6b2 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -34,13 +34,17 @@ #include #include +#include "HTTPStream.h" + namespace android { // static const int64_t ARTSPConnection::kSelectTimeoutUs = 1000ll; -ARTSPConnection::ARTSPConnection() - : mState(DISCONNECTED), +ARTSPConnection::ARTSPConnection(bool uidValid, uid_t uid) + : mUIDValid(uidValid), + mUID(uid), + mState(DISCONNECTED), mAuthType(NONE), mSocket(-1), mConnectionID(0), @@ -246,6 +250,10 @@ void ARTSPConnection::onConnect(const sp &msg) { mSocket = socket(AF_INET, SOCK_STREAM, 0); + if (mUIDValid) { + HTTPStream::RegisterSocketUser(mSocket, mUID); + } + MakeSocketBlocking(mSocket, false); struct sockaddr_in remote; diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h index ac2e3ae..5cb84fd 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.h +++ b/media/libstagefright/rtsp/ARTSPConnection.h @@ -33,7 +33,7 @@ struct ARTSPResponse : public RefBase { }; struct ARTSPConnection : public AHandler { - ARTSPConnection(); + ARTSPConnection(bool uidValid = false, uid_t uid = 0); void connect(const char *url, const sp &reply); void disconnect(const sp &reply); @@ -74,6 +74,8 @@ private: static const int64_t kSelectTimeoutUs; + bool mUIDValid; + uid_t mUID; State mState; AString mUser, mPass; AuthType mAuthType; diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp index 1328d2e..2ebae7e 100644 --- a/media/libstagefright/rtsp/ARTSPController.cpp +++ b/media/libstagefright/rtsp/ARTSPController.cpp @@ -28,6 +28,7 @@ namespace android { ARTSPController::ARTSPController(const sp &looper) : mState(DISCONNECTED), mLooper(looper), + mUIDValid(false), mSeekDoneCb(NULL), mSeekDoneCookie(NULL), mLastSeekCompletedTimeUs(-1) { @@ -40,6 +41,11 @@ ARTSPController::~ARTSPController() { mLooper->unregisterHandler(mReflector->id()); } +void ARTSPController::setUID(uid_t uid) { + mUIDValid = true; + mUID = uid; +} + status_t ARTSPController::connect(const char *url) { Mutex::Autolock autoLock(mLock); @@ -49,7 +55,7 @@ status_t ARTSPController::connect(const char *url) { sp msg = new AMessage(kWhatConnectDone, mReflector->id()); - mHandler = new MyHandler(url, mLooper); + mHandler = new MyHandler(url, mLooper, mUIDValid, mUID); mState = CONNECTING; diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index d15d9c5..3188959 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -40,6 +40,8 @@ #include #include +#include "HTTPStream.h" + // If no access units are received within 5 secs, assume that the rtp // stream has ended and signal end of stream. static int64_t kAccessUnitTimeoutUs = 5000000ll; @@ -92,10 +94,14 @@ static bool GetAttribute(const char *s, const char *key, AString *value) { } struct MyHandler : public AHandler { - MyHandler(const char *url, const sp &looper) - : mLooper(looper), + MyHandler( + const char *url, const sp &looper, + bool uidValid = false, uid_t uid = 0) + : mUIDValid(uidValid), + mUID(uid), + mLooper(looper), mNetLooper(new ALooper), - mConn(new ARTSPConnection), + mConn(new ARTSPConnection(mUIDValid, mUID)), mRTPConn(new ARTPConnection), mOriginalSessionURL(url), mSessionURL(url), @@ -1078,6 +1084,8 @@ private: List > mPackets; }; + bool mUIDValid; + uid_t mUID; sp mLooper; sp mNetLooper; sp mConn; @@ -1172,6 +1180,11 @@ private: ARTPConnection::MakePortPair( &info->mRTPSocket, &info->mRTCPSocket, &rtpPort); + if (mUIDValid) { + HTTPStream::RegisterSocketUser(info->mRTPSocket, mUID); + HTTPStream::RegisterSocketUser(info->mRTCPSocket, mUID); + } + request.append("Transport: RTP/AVP/UDP;unicast;client_port="); request.append(rtpPort); request.append("-"); -- cgit v1.1