ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/utils/adbd/src/include/sysutils/FrameworkClient.h b/package/utils/adbd/src/include/sysutils/FrameworkClient.h
new file mode 100644
index 0000000..4a3f0de
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/FrameworkClient.h
@@ -0,0 +1,21 @@
+#ifndef _FRAMEWORK_CLIENT_H
+#define _FRAMEWORK_CLIENT_H
+
+#include "List.h"
+
+#include <pthread.h>
+
+class FrameworkClient {
+    int             mSocket;
+    pthread_mutex_t mWriteMutex;
+
+public:
+    FrameworkClient(int sock);
+    virtual ~FrameworkClient() {}
+
+    int sendMsg(const char *msg);
+    int sendMsg(const char *msg, const char *data);
+};
+
+typedef android::sysutils::List<FrameworkClient *> FrameworkClientCollection;
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/FrameworkCommand.h b/package/utils/adbd/src/include/sysutils/FrameworkCommand.h
new file mode 100644
index 0000000..3e6264b
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/FrameworkCommand.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __FRAMEWORK_CMD_HANDLER_H
+#define __FRAMEWORK_CMD_HANDLER_H
+
+#include "List.h"
+
+class SocketClient;
+
+class FrameworkCommand { 
+private:
+    const char *mCommand;
+
+public:
+
+    FrameworkCommand(const char *cmd);
+    virtual ~FrameworkCommand() { }
+
+    virtual int runCommand(SocketClient *c, int argc, char **argv) = 0;
+
+    const char *getCommand() { return mCommand; }
+};
+
+typedef android::sysutils::List<FrameworkCommand *> FrameworkCommandCollection;
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/FrameworkListener.h b/package/utils/adbd/src/include/sysutils/FrameworkListener.h
new file mode 100644
index 0000000..18049cd
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/FrameworkListener.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _FRAMEWORKSOCKETLISTENER_H
+#define _FRAMEWORKSOCKETLISTENER_H
+
+#include "SocketListener.h"
+#include "FrameworkCommand.h"
+
+class SocketClient;
+
+class FrameworkListener : public SocketListener {
+public:
+    static const int CMD_ARGS_MAX = 26;
+
+    /* 1 out of errorRate will be dropped */
+    int errorRate;
+
+private:
+    int mCommandCount;
+    bool mWithSeq;
+    FrameworkCommandCollection *mCommands;
+
+public:
+    FrameworkListener(const char *socketName);
+    FrameworkListener(const char *socketName, bool withSeq);
+    FrameworkListener(int sock);
+    virtual ~FrameworkListener() {}
+
+protected:
+    void registerCmd(FrameworkCommand *cmd);
+    virtual bool onDataAvailable(SocketClient *c);
+
+private:
+    void dispatchCommand(SocketClient *c, char *data);
+    void init(const char *socketName, bool withSeq);
+};
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/List.h b/package/utils/adbd/src/include/sysutils/List.h
new file mode 100644
index 0000000..31f7b37
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/List.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Templated list class.  Normally we'd use STL, but we don't have that.
+// This class mimics STL's interfaces.
+//
+// Objects are copied into the list with the '=' operator or with copy-
+// construction, so if the compiler's auto-generated versions won't work for
+// you, define your own.
+//
+// The only class you want to use from here is "List".
+//
+#ifndef _SYSUTILS_LIST_H
+#define _SYSUTILS_LIST_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace android {
+namespace sysutils {
+
+/*
+ * Doubly-linked list.  Instantiate with "List<MyClass> myList".
+ *
+ * Objects added to the list are copied using the assignment operator,
+ * so this must be defined.
+ */
+template<typename T> 
+class List 
+{
+protected:
+    /*
+     * One element in the list.
+     */
+    class _Node {
+    public:
+        explicit _Node(const T& val) : mVal(val) {}
+        ~_Node() {}
+        inline T& getRef() { return mVal; }
+        inline const T& getRef() const { return mVal; }
+        inline _Node* getPrev() const { return mpPrev; }
+        inline _Node* getNext() const { return mpNext; }
+        inline void setVal(const T& val) { mVal = val; }
+        inline void setPrev(_Node* ptr) { mpPrev = ptr; }
+        inline void setNext(_Node* ptr) { mpNext = ptr; }
+    private:
+        friend class List;
+        friend class _ListIterator;
+        T           mVal;
+        _Node*      mpPrev;
+        _Node*      mpNext;
+    };
+
+    /*
+     * Iterator for walking through the list.
+     */
+    
+    template <typename TYPE>
+    struct CONST_ITERATOR {
+        typedef _Node const * NodePtr;
+        typedef const TYPE Type;
+    };
+    
+    template <typename TYPE>
+    struct NON_CONST_ITERATOR {
+        typedef _Node* NodePtr;
+        typedef TYPE Type;
+    };
+    
+    template<
+        typename U,
+        template <class> class Constness
+    > 
+    class _ListIterator {
+        typedef _ListIterator<U, Constness>     _Iter;
+        typedef typename Constness<U>::NodePtr  _NodePtr;
+        typedef typename Constness<U>::Type     _Type;
+
+        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
+
+    public:
+        _ListIterator() {}
+        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
+        ~_ListIterator() {}
+        
+        // this will handle conversions from iterator to const_iterator
+        // (and also all convertible iterators)
+        // Here, in this implementation, the iterators can be converted
+        // if the nodes can be converted
+        template<typename V> explicit 
+        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
+        
+
+        /*
+         * Dereference operator.  Used to get at the juicy insides.
+         */
+        _Type& operator*() const { return mpNode->getRef(); }
+        _Type* operator->() const { return &(mpNode->getRef()); }
+
+        /*
+         * Iterator comparison.
+         */
+        inline bool operator==(const _Iter& right) const { 
+            return mpNode == right.mpNode; }
+        
+        inline bool operator!=(const _Iter& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * handle comparisons between iterator and const_iterator
+         */
+        template<typename OTHER>
+        inline bool operator==(const OTHER& right) const { 
+            return mpNode == right.mpNode; }
+        
+        template<typename OTHER>
+        inline bool operator!=(const OTHER& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * Incr/decr, used to move through the list.
+         */
+        inline _Iter& operator++() {     // pre-increment
+            mpNode = mpNode->getNext();
+            return *this;
+        }
+        const _Iter operator++(int) {    // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getNext();
+            return tmp;
+        }
+        inline _Iter& operator--() {     // pre-increment
+            mpNode = mpNode->getPrev();
+            return *this;
+        }
+        const _Iter operator--(int) {   // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getPrev();
+            return tmp;
+        }
+
+        inline _NodePtr getNode() const { return mpNode; }
+
+        _NodePtr mpNode;    /* should be private, but older gcc fails */
+    private:
+        friend class List;
+    };
+
+public:
+    List() {
+        prep();
+    }
+    List(const List<T>& src) {      // copy-constructor
+        prep();
+        insert(begin(), src.begin(), src.end());
+    }
+    virtual ~List() {
+        clear();
+        delete[] (unsigned char*) mpMiddle;
+    }
+
+    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
+    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
+
+    List<T>& operator=(const List<T>& right);
+
+    /* returns true if the list is empty */
+    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
+
+    /* return #of elements in list */
+    size_t size() const {
+        return size_t(distance(begin(), end()));
+    }
+
+    /*
+     * Return the first element or one past the last element.  The
+     * _Node* we're returning is converted to an "iterator" by a
+     * constructor in _ListIterator.
+     */
+    inline iterator begin() { 
+        return iterator(mpMiddle->getNext()); 
+    }
+    inline const_iterator begin() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); 
+    }
+    inline iterator end() { 
+        return iterator(mpMiddle); 
+    }
+    inline const_iterator end() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle)); 
+    }
+
+    /* add the object to the head or tail of the list */
+    void push_front(const T& val) { insert(begin(), val); }
+    void push_back(const T& val) { insert(end(), val); }
+
+    /* insert before the current node; returns iterator at new node */
+    iterator insert(iterator posn, const T& val) 
+    {
+        _Node* newNode = new _Node(val);        // alloc & copy-construct
+        newNode->setNext(posn.getNode());
+        newNode->setPrev(posn.getNode()->getPrev());
+        posn.getNode()->getPrev()->setNext(newNode);
+        posn.getNode()->setPrev(newNode);
+        return iterator(newNode);
+    }
+
+    /* insert a range of elements before the current node */
+    void insert(iterator posn, const_iterator first, const_iterator last) {
+        for ( ; first != last; ++first)
+            insert(posn, *first);
+    }
+
+    /* remove one entry; returns iterator at next node */
+    iterator erase(iterator posn) {
+        _Node* pNext = posn.getNode()->getNext();
+        _Node* pPrev = posn.getNode()->getPrev();
+        pPrev->setNext(pNext);
+        pNext->setPrev(pPrev);
+        delete posn.getNode();
+        return iterator(pNext);
+    }
+
+    /* remove a range of elements */
+    iterator erase(iterator first, iterator last) {
+        while (first != last)
+            erase(first++);     // don't erase than incr later!
+        return iterator(last);
+    }
+
+    /* remove all contents of the list */
+    void clear() {
+        _Node* pCurrent = mpMiddle->getNext();
+        _Node* pNext;
+
+        while (pCurrent != mpMiddle) {
+            pNext = pCurrent->getNext();
+            delete pCurrent;
+            pCurrent = pNext;
+        }
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * Measure the distance between two iterators.  On exist, "first"
+     * will be equal to "last".  The iterators must refer to the same
+     * list.
+     *
+     * FIXME: This is actually a generic iterator function. It should be a 
+     * template function at the top-level with specializations for things like
+     * vector<>, which can just do pointer math). Here we limit it to
+     * _ListIterator of the same type but different constness.
+     */
+    template<
+        typename U,
+        template <class> class CL,
+        template <class> class CR
+    > 
+    ptrdiff_t distance(
+            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const 
+    {
+        ptrdiff_t count = 0;
+        while (first != last) {
+            ++first;
+            ++count;
+        }
+        return count;
+    }
+
+private:
+    /*
+     * I want a _Node but don't need it to hold valid data.  More
+     * to the point, I don't want T's constructor to fire, since it
+     * might have side-effects or require arguments.  So, we do this
+     * slightly uncouth storage alloc.
+     */
+    void prep() {
+        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * This node plays the role of "pointer to head" and "pointer to tail".
+     * It sits in the middle of a circular list of nodes.  The iterator
+     * runs around the circle until it encounters this one.
+     */
+    _Node*      mpMiddle;
+};
+
+/*
+ * Assignment operator.
+ *
+ * The simplest way to do this would be to clear out the target list and
+ * fill it with the source.  However, we can speed things along by
+ * re-using existing elements.
+ */
+template<class T>
+List<T>& List<T>::operator=(const List<T>& right)
+{
+    if (this == &right)
+        return *this;       // self-assignment
+    iterator firstDst = begin();
+    iterator lastDst = end();
+    const_iterator firstSrc = right.begin();
+    const_iterator lastSrc = right.end();
+    while (firstSrc != lastSrc && firstDst != lastDst)
+        *firstDst++ = *firstSrc++;
+    if (firstSrc == lastSrc)        // ran out of elements in source?
+        erase(firstDst, lastDst);   // yes, erase any extras
+    else
+        insert(lastDst, firstSrc, lastSrc);     // copy remaining over
+    return *this;
+}
+
+}; // namespace sysutils
+}; // namespace android
+
+#endif // _SYSUTILS_LIST_H
diff --git a/package/utils/adbd/src/include/sysutils/NetlinkEvent.h b/package/utils/adbd/src/include/sysutils/NetlinkEvent.h
new file mode 100644
index 0000000..c345cdb
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/NetlinkEvent.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _NETLINKEVENT_H
+#define _NETLINKEVENT_H
+
+#include <sysutils/NetlinkListener.h>
+
+#define NL_PARAMS_MAX 32
+
+class NetlinkEvent {
+    int  mSeq;
+    char *mPath;
+    int  mAction;
+    char *mSubsystem;
+    char *mParams[NL_PARAMS_MAX];
+
+public:
+    const static int NlActionUnknown;
+    const static int NlActionAdd;
+    const static int NlActionRemove;
+    const static int NlActionChange;
+    const static int NlActionLinkDown;
+    const static int NlActionLinkUp;
+    const static int NlActionAddressUpdated;
+    const static int NlActionAddressRemoved;
+    const static int NlActionRdnss;
+    const static int NlActionRouteUpdated;
+    const static int NlActionRouteRemoved;
+
+    NetlinkEvent();
+    virtual ~NetlinkEvent();
+
+    bool decode(char *buffer, int size, int format = NetlinkListener::NETLINK_FORMAT_ASCII);
+    const char *findParam(const char *paramName);
+
+    const char *getSubsystem() { return mSubsystem; }
+    int getAction() { return mAction; }
+
+    void dump();
+
+ protected:
+    bool parseBinaryNetlinkMessage(char *buffer, int size);
+    bool parseAsciiNetlinkMessage(char *buffer, int size);
+    bool parseIfInfoMessage(const struct nlmsghdr *nh);
+    bool parseIfAddrMessage(const struct nlmsghdr *nh);
+    bool parseUlogPacketMessage(const struct nlmsghdr *nh);
+    bool parseRtMessage(const struct nlmsghdr *nh);
+    bool parseNdUserOptMessage(const struct nlmsghdr *nh);
+};
+
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/NetlinkListener.h b/package/utils/adbd/src/include/sysutils/NetlinkListener.h
new file mode 100644
index 0000000..6e52c3b
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/NetlinkListener.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _NETLINKLISTENER_H
+#define _NETLINKLISTENER_H
+
+#include "SocketListener.h"
+
+class NetlinkEvent;
+
+class NetlinkListener : public SocketListener {
+    char mBuffer[64 * 1024] __attribute__((aligned(4)));
+    int mFormat;
+
+public:
+    static const int NETLINK_FORMAT_ASCII = 0;
+    static const int NETLINK_FORMAT_BINARY = 1;
+
+#if 1
+    /* temporary version until we can get Motorola to update their
+     * ril.so.  Their prebuilt ril.so is using this private class
+     * so changing the NetlinkListener() constructor breaks their ril.
+     */
+    NetlinkListener(int socket);
+    NetlinkListener(int socket, int format);
+#else
+    NetlinkListener(int socket, int format = NETLINK_FORMAT_ASCII);
+#endif
+    virtual ~NetlinkListener() {}
+
+protected:
+    virtual bool onDataAvailable(SocketClient *cli);
+    virtual void onEvent(NetlinkEvent *evt) = 0;
+};
+
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/ServiceManager.h b/package/utils/adbd/src/include/sysutils/ServiceManager.h
new file mode 100644
index 0000000..c31dd8f
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/ServiceManager.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SERVICE_MANAGER_H
+#define _SERVICE_MANAGER_H
+
+class ServiceManager {
+public:
+    ServiceManager();
+    virtual ~ServiceManager() {}
+
+    int start(const char *name);
+    int stop(const char *name);
+    bool isRunning(const char *name);
+};
+
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/SocketClient.h b/package/utils/adbd/src/include/sysutils/SocketClient.h
new file mode 100644
index 0000000..1004f06
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/SocketClient.h
@@ -0,0 +1,88 @@
+#ifndef _SOCKET_CLIENT_H
+#define _SOCKET_CLIENT_H
+
+#include "List.h"
+
+#include <pthread.h>
+#include <cutils/atomic.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+class SocketClient {
+    int             mSocket;
+    bool            mSocketOwned;
+    pthread_mutex_t mWriteMutex;
+
+    // Peer process ID
+    pid_t mPid;
+
+    // Peer user ID
+    uid_t mUid;
+
+    // Peer group ID
+    gid_t mGid;
+
+    // Reference count (starts at 1)
+    pthread_mutex_t mRefCountMutex;
+    int mRefCount;
+
+    int mCmdNum;
+
+    bool mUseCmdNum;
+
+public:
+    SocketClient(int sock, bool owned);
+    SocketClient(int sock, bool owned, bool useCmdNum);
+    virtual ~SocketClient();
+
+    int getSocket() { return mSocket; }
+    pid_t getPid() const { return mPid; }
+    uid_t getUid() const { return mUid; }
+    gid_t getGid() const { return mGid; }
+    void setCmdNum(int cmdNum) {
+        android_atomic_release_store(cmdNum, &mCmdNum);
+    }
+    int getCmdNum() { return mCmdNum; }
+
+    // Send null-terminated C strings:
+    int sendMsg(int code, const char *msg, bool addErrno);
+    int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum);
+    int sendMsg(const char *msg);
+
+    // Provides a mechanism to send a response code to the client.
+    // Sends the code and a null character.
+    int sendCode(int code);
+
+    // Provides a mechanism to send binary data to client.
+    // Sends the code and a null character, followed by 4 bytes of
+    // big-endian length, and the data.
+    int sendBinaryMsg(int code, const void *data, int len);
+
+    // Sending binary data:
+    int sendData(const void *data, int len);
+    // iovec contents not preserved through call
+    int sendDatav(struct iovec *iov, int iovcnt);
+
+    // Optional reference counting.  Reference count starts at 1.  If
+    // it's decremented to 0, it deletes itself.
+    // SocketListener creates a SocketClient (at refcount 1) and calls
+    // decRef() when it's done with the client.
+    void incRef();
+    bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
+
+    // return a new string in quotes with '\\' and '\"' escaped for "my arg"
+    // transmissions
+    static char *quoteArg(const char *arg);
+
+private:
+    void init(int socket, bool owned, bool useCmdNum);
+
+    // Sending binary data. The caller should make sure this is protected
+    // from multiple threads entering simultaneously.
+    // returns 0 if successful, -1 if there is a 0 byte write or if any
+    // other error occurred (use errno to get the error)
+    int sendDataLockedv(struct iovec *iov, int iovcnt);
+};
+
+typedef android::sysutils::List<SocketClient *> SocketClientCollection;
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/SocketClientCommand.h b/package/utils/adbd/src/include/sysutils/SocketClientCommand.h
new file mode 100644
index 0000000..746bc25
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/SocketClientCommand.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _SOCKETCLIENTCOMMAND_H
+#define _SOCKETCLIENTCOMMAND_H
+
+#include <sysutils/SocketClient.h>
+
+class SocketClientCommand {
+public:
+    virtual ~SocketClientCommand() { }
+    virtual void runSocketCommand(SocketClient *client) = 0;
+};
+
+#endif
diff --git a/package/utils/adbd/src/include/sysutils/SocketListener.h b/package/utils/adbd/src/include/sysutils/SocketListener.h
new file mode 100644
index 0000000..bc93b86
--- /dev/null
+++ b/package/utils/adbd/src/include/sysutils/SocketListener.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _SOCKETLISTENER_H
+#define _SOCKETLISTENER_H
+
+#include <pthread.h>
+
+#include <sysutils/SocketClient.h>
+#include "SocketClientCommand.h"
+
+class SocketListener {
+    bool                    mListen;
+    const char              *mSocketName;
+    int                     mSock;
+    SocketClientCollection  *mClients;
+    pthread_mutex_t         mClientsLock;
+    int                     mCtrlPipe[2];
+    pthread_t               mThread;
+    bool                    mUseCmdNum;
+
+public:
+    SocketListener(const char *socketName, bool listen);
+    SocketListener(const char *socketName, bool listen, bool useCmdNum);
+    SocketListener(int socketFd, bool listen);
+
+    virtual ~SocketListener();
+    int startListener();
+    int startListener(int backlog);
+    int stopListener();
+
+    void sendBroadcast(int code, const char *msg, bool addErrno);
+
+    void runOnEachSocket(SocketClientCommand *command);
+
+    bool release(SocketClient *c) { return release(c, true); }
+
+protected:
+    virtual bool onDataAvailable(SocketClient *c) = 0;
+
+private:
+    bool release(SocketClient *c, bool wakeup);
+    static void *threadStart(void *obj);
+    void runListener();
+    void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
+};
+#endif