Merge "Charge network traffic to the uid of the process using the MediaPlayer."
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 18e8a5f..4328d3c 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -103,6 +103,10 @@
     virtual status_t    initCheck() = 0;
     virtual bool        hardwareOutput() = 0;
 
+    virtual status_t    setUID(uid_t uid) {
+        return INVALID_OPERATION;
+    }
+
     virtual status_t    setDataSource(
             const char *url,
             const KeyedVector<String8, String8> *headers = NULL) = 0;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a77dff1..1e7c969 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -250,7 +250,11 @@
         const KeyedVector<String8, String8> *headers, int audioSessionId)
 {
     int32_t connId = android_atomic_inc(&mNextConnId);
-    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+    sp<Client> c = new Client(
+            this, pid, connId, client, audioSessionId,
+            IPCThreadState::self()->getCallingUid());
+
     LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d",
             connId, pid, url, connId, audioSessionId);
     if (NO_ERROR != c->setDataSource(url, headers))
@@ -268,7 +272,11 @@
         int fd, int64_t offset, int64_t length, int audioSessionId)
 {
     int32_t connId = android_atomic_inc(&mNextConnId);
-    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+    sp<Client> c = new Client(
+            this, pid, connId, client, audioSessionId,
+            IPCThreadState::self()->getCallingUid());
+
     LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d",
             connId, pid, fd, offset, length, audioSessionId);
     if (NO_ERROR != c->setDataSource(fd, offset, length)) {
@@ -286,7 +294,10 @@
         pid_t pid, const sp<IMediaPlayerClient> &client,
         const sp<IStreamSource> &source, int audioSessionId) {
     int32_t connId = android_atomic_inc(&mNextConnId);
-    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+    sp<Client> c = new Client(
+            this, pid, connId, client, audioSessionId,
+            IPCThreadState::self()->getCallingUid());
 
     LOGV("Create new client(%d) from pid %d, audioSessionId=%d",
          connId, pid, audioSessionId);
@@ -496,8 +507,10 @@
     mClients.remove(client);
 }
 
-MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
-        int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId)
+MediaPlayerService::Client::Client(
+        const sp<MediaPlayerService>& service, pid_t pid,
+        int32_t connId, const sp<IMediaPlayerClient>& client,
+        int audioSessionId, uid_t uid)
 {
     LOGV("Client(%d) constructor", connId);
     mPid = pid;
@@ -507,6 +520,7 @@
     mLoop = false;
     mStatus = NO_INIT;
     mAudioSessionId = audioSessionId;
+    mUID = uid;
 
 #if CALLBACK_ANTAGONIZER
     LOGD("create Antagonizer");
@@ -671,6 +685,9 @@
     if (p == NULL) {
         p = android::createPlayer(playerType, this, notify);
     }
+
+    p->setUID(mUID);
+
     return p;
 }
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 8bab471..e32b92a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -306,7 +306,8 @@
                                         pid_t pid,
                                         int32_t connId,
                                         const sp<IMediaPlayerClient>& client,
-                                        int audioSessionId);
+                                        int audioSessionId,
+                                        uid_t uid);
                                 Client();
         virtual                 ~Client();
 
@@ -336,6 +337,7 @@
                     bool                        mLoop;
                     int32_t                     mConnId;
                     int                         mAudioSessionId;
+                    uid_t                       mUID;
 
         // Metadata filters.
         media::Metadata::Filter mMetadataAllow;  // protected by mLock
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 870e290..40e055c 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -47,6 +47,12 @@
     return OK;
 }
 
+status_t StagefrightPlayer::setUID(uid_t uid) {
+    mPlayer->setUID(uid);
+
+    return OK;
+}
+
 status_t StagefrightPlayer::setDataSource(
         const char *url, const KeyedVector<String8, String8> *headers) {
     return mPlayer->setDataSource(url, headers);
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index 85a546d..cbc6d49 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -31,6 +31,8 @@
 
     virtual status_t initCheck();
 
+    virtual status_t setUID(uid_t uid);
+
     virtual status_t setDataSource(
             const char *url, const KeyedVector<String8, String8> *headers);
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index b3b3af5..5a5330d 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -35,8 +35,11 @@
 
 NuPlayer::HTTPLiveSource::HTTPLiveSource(
         const char *url,
-        const KeyedVector<String8, String8> *headers)
+        const KeyedVector<String8, String8> *headers,
+        bool uidValid, uid_t uid)
     : mURL(url),
+      mUIDValid(uidValid),
+      mUID(uid),
       mFlags(0),
       mEOS(false),
       mOffset(0) {
@@ -65,7 +68,8 @@
     mLiveLooper->start();
 
     mLiveSession = new LiveSession(
-            (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0);
+            (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
+            mUIDValid, mUID);
 
     mLiveLooper->registerHandler(mLiveSession);
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index 7a337e9..36c67c5 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -29,7 +29,9 @@
 struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {
     HTTPLiveSource(
             const char *url,
-            const KeyedVector<String8, String8> *headers);
+            const KeyedVector<String8, String8> *headers,
+            bool uidValid = false,
+            uid_t uid = 0);
 
     virtual void start();
 
@@ -54,6 +56,8 @@
 
     AString mURL;
     KeyedVector<String8, String8> mExtraHeaders;
+    bool mUIDValid;
+    uid_t mUID;
     uint32_t mFlags;
     bool mEOS;
     off64_t mOffset;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index effa703..b06f20d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -44,7 +44,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 NuPlayer::NuPlayer()
-    : mAudioEOS(false),
+    : mUIDValid(false),
+      mAudioEOS(false),
       mVideoEOS(false),
       mScanSourcesPending(false),
       mScanSourcesGeneration(0),
@@ -57,6 +58,11 @@
 NuPlayer::~NuPlayer() {
 }
 
+void NuPlayer::setUID(uid_t uid) {
+    mUIDValid = true;
+    mUID = uid;
+}
+
 void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
     mDriver = driver;
 }
@@ -72,7 +78,7 @@
         const char *url, const KeyedVector<String8, String8> *headers) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
-    msg->setObject("source", new HTTPLiveSource(url, headers));
+    msg->setObject("source", new HTTPLiveSource(url, headers, mUIDValid, mUID));
     msg->post();
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index fb5b001..cf9185b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -33,6 +33,8 @@
 struct NuPlayer : public AHandler {
     NuPlayer();
 
+    void setUID(uid_t uid);
+
     void setDriver(const wp<NuPlayerDriver> &driver);
 
     void setDataSource(const sp<IStreamSource> &source);
@@ -84,6 +86,8 @@
     };
 
     wp<NuPlayerDriver> mDriver;
+    bool mUIDValid;
+    uid_t mUID;
     sp<Source> mSource;
     sp<NativeWindowWrapper> mNativeWindow;
     sp<MediaPlayerBase::AudioSink> mAudioSink;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index e1213f4..7cd8b6c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -55,6 +55,12 @@
     return OK;
 }
 
+status_t NuPlayerDriver::setUID(uid_t uid) {
+    mPlayer->setUID(uid);
+
+    return OK;
+}
+
 status_t NuPlayerDriver::setDataSource(
         const char *url, const KeyedVector<String8, String8> *headers) {
     CHECK_EQ((int)mState, (int)UNINITIALIZED);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 145fd80..1bb7ca2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -28,6 +28,8 @@
 
     virtual status_t initCheck();
 
+    virtual status_t setUID(uid_t uid);
+
     virtual status_t setDataSource(
             const char *url, const KeyedVector<String8, String8> *headers);
 
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 @@
 ////////////////////////////////////////////////////////////////////////////////
 AwesomePlayer::AwesomePlayer()
     : mQueueStarted(false),
+      mUIDValid(false),
       mTimeSource(NULL),
       mVideoRendererIsPreview(false),
       mAudioPlayer(NULL),
@@ -243,6 +244,13 @@
     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<String8, String8> *headers) {
     Mutex::Autolock autoLock(mLock);
@@ -1928,6 +1936,10 @@
                     ? HTTPBase::kFlagIncognito
                     : 0);
 
+        if (mUIDValid) {
+            mConnectingDataSource->setUID(mUID);
+        }
+
         mLock.unlock();
         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
         mLock.lock();
@@ -2009,6 +2021,10 @@
         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 @@
       mTotalTransferBytes(0),
       mPrevBandwidthMeasureTimeUs(0),
       mPrevEstimatedBandWidthKbps(0),
-      mBandWidthCollectFreqMs(5000) {
+      mBandWidthCollectFreqMs(5000),
+      mUIDValid(false) {
 }
 
 // static
@@ -119,4 +120,19 @@
     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 @@
 
 HTTPStream::HTTPStream()
     : mState(READY),
+      mUIDValid(false),
       mSocket(-1),
       mSSLContext(NULL),
       mSSL(NULL) {
@@ -57,6 +58,11 @@
     }
 }
 
+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 @@
             continue;
         }
 
+        if (mUIDValid) {
+            RegisterSocketUser(mSocket, mUID);
+        }
+
         setReceiveTimeout(30);  // Time out reads after 30 secs by default.
 
         int s = mSocket;
@@ -596,5 +606,18 @@
     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 @@
         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 @@
 
 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 @@
       mSeekDone(false),
       mDisconnectPending(false),
       mMonitorQueueGeneration(0) {
+    if (mUIDValid) {
+        mHTTPDataSource->setUID(mUID);
+    }
 }
 
 LiveSession::~LiveSession() {
@@ -671,6 +676,10 @@
                     ? 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 ARTSPController : public MediaExtractor {
     ARTSPController(const sp<ALooper> &looper);
 
+    void setUID(uid_t uid);
+
     status_t connect(const char *url);
     void disconnect();
 
@@ -80,6 +82,9 @@
     sp<MyHandler> mHandler;
     sp<AHandlerReflector<ARTSPController> > 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 @@
     ~AwesomePlayer();
 
     void setListener(const wp<MediaPlayerBase> &listener);
+    void setUID(uid_t uid);
 
     status_t setDataSource(
             const char *uri,
@@ -150,6 +151,8 @@
     TimedEventQueue mQueue;
     bool mQueueStarted;
     wp<MediaPlayerBase> mListener;
+    bool mUIDValid;
+    uid_t mUID;
 
     sp<Surface> mSurface;
     sp<ANativeWindow> 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 @@
 
     virtual status_t setBandwidthStatCollectFreq(int32_t freqMs);
 
+    void setUID(uid_t uid);
+    bool getUID(uid_t *uid) const;
+
     static sp<HTTPBase> 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 @@
     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 @@
     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 @@
     // _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 @@
 
     State mState;
     Mutex mLock;
+
+    bool mUIDValid;
+    uid_t mUID;
+
     int mSocket;
 
     KeyedVector<AString, AString> 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 @@
         // 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<DataSource> getDataSource();
 
@@ -77,6 +77,8 @@
     };
 
     uint32_t mFlags;
+    bool mUIDValid;
+    uid_t mUID;
 
     sp<LiveDataSource> 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 <openssl/md5.h>
 #include <sys/socket.h>
 
+#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 @@
 
     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 ARTSPConnection : public AHandler {
-    ARTSPConnection();
+    ARTSPConnection(bool uidValid = false, uid_t uid = 0);
 
     void connect(const char *url, const sp<AMessage> &reply);
     void disconnect(const sp<AMessage> &reply);
@@ -74,6 +74,8 @@
 
     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 @@
 ARTSPController::ARTSPController(const sp<ALooper> &looper)
     : mState(DISCONNECTED),
       mLooper(looper),
+      mUIDValid(false),
       mSeekDoneCb(NULL),
       mSeekDoneCookie(NULL),
       mLastSeekCompletedTimeUs(-1) {
@@ -40,6 +41,11 @@
     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 @@
 
     sp<AMessage> 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 <sys/socket.h>
 #include <netdb.h>
 
+#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 @@
 }
 
 struct MyHandler : public AHandler {
-    MyHandler(const char *url, const sp<ALooper> &looper)
-        : mLooper(looper),
+    MyHandler(
+            const char *url, const sp<ALooper> &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 @@
         List<sp<ABuffer> > mPackets;
     };
 
+    bool mUIDValid;
+    uid_t mUID;
     sp<ALooper> mLooper;
     sp<ALooper> mNetLooper;
     sp<ARTSPConnection> mConn;
@@ -1172,6 +1180,11 @@
             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("-");