Android's Media

MediaService.Main

 1 #include <sys/types.h>
 2 #include <unistd.h>
 3 #include <grp.h>
 4 
 5 #include <binder/IPCThreadState.h>
 6 #include <binder/ProcessState.h>
 7 #include <binder/IServiceManager.h>
 8 #include <utils/Log.h>
 9 
10 #include <AudioFlinger.h>
11 #include <CameraService.h>
12 #include <MediaPlayerService.h>
13 #include <AudioPolicyService.h>
14 #include <private/android_filesystem_config.h>
15 
16 using namespace android;
17 
18 int main(int argc, char** argv)
19 {
20     sp<ProcessState> proc(ProcessState::self());
21     sp<IServiceManager> sm = defaultServiceManager();
22     LOGI("ServiceManager: %p", sm.get());
23     AudioFlinger::instantiate();
24     MediaPlayerService::instantiate();
25     CameraService::instantiate();
26     AudioPolicyService::instantiate();
27     ProcessState::self()->startThreadPool();
28     IPCThreadState::self()->joinThreadPool();
29 }
View Code
  1.  1 int main(int argc, char** argv)
     2 {
     3     sp<ProcessState> proc(ProcessState::self());
     4     sp<IServiceManager> sm = defaultServiceManager();
     5     LOGI("ServiceManager: %p", sm.get());
     6     AudioFlinger::instantiate();
     7     MediaPlayerService::instantiate();
     8     CameraService::instantiate();
     9     AudioPolicyService::instantiate();
    10     ProcessState::self()->startThreadPool();
    11     IPCThreadState::self()->joinThreadPool();
    12 }
  • What is sp?   include/utils/StrongPointer.h
  •   1 #ifndef ANDROID_STRONG_POINTER_H
      2 #define ANDROID_STRONG_POINTER_H
      3 
      4 #include <cutils/atomic.h>
      5 
      6 #include <stdint.h>
      7 #include <sys/types.h>
      8 #include <stdlib.h>
      9 
     10 // ---------------------------------------------------------------------------
     11 namespace android {
     12 
     13 class TextOutput;
     14 TextOutput& printStrongPointer(TextOutput& to, const void* val);
     15 
     16 template<typename T> class wp;
     17 
     18 // ---------------------------------------------------------------------------
     19 
     20 #define COMPARE(_op_)                                           
     21 inline bool operator _op_ (const sp<T>& o) const {              
     22     return m_ptr _op_ o.m_ptr;                                  
     23 }                                                               
     24 inline bool operator _op_ (const T* o) const {                  
     25     return m_ptr _op_ o;                                        
     26 }                                                               
     27 template<typename U>                                            
     28 inline bool operator _op_ (const sp<U>& o) const {              
     29     return m_ptr _op_ o.m_ptr;                                  
     30 }                                                               
     31 template<typename U>                                            
     32 inline bool operator _op_ (const U* o) const {                  
     33     return m_ptr _op_ o;                                        
     34 }                                                               
     35 inline bool operator _op_ (const wp<T>& o) const {              
     36     return m_ptr _op_ o.m_ptr;                                  
     37 }                                                               
     38 template<typename U>                                            
     39 inline bool operator _op_ (const wp<U>& o) const {              
     40     return m_ptr _op_ o.m_ptr;                                  
     41 }
     42 
     43 // ---------------------------------------------------------------------------
     44 
     45 template <typename T>
     46 class sp
     47 {
     48 public:
     49     inline sp() : m_ptr(0) { }
     50 
     51     sp(T* other);
     52     sp(const sp<T>& other);
     53     template<typename U> sp(U* other);
     54     template<typename U> sp(const sp<U>& other);
     55 
     56     ~sp();
     57 
     58     // Assignment
     59 
     60     sp& operator = (T* other);
     61     sp& operator = (const sp<T>& other);
     62 
     63     template<typename U> sp& operator = (const sp<U>& other);
     64     template<typename U> sp& operator = (U* other);
     65 
     66     //! Special optimization for use by ProcessState (and nobody else).
     67     void force_set(T* other);
     68 
     69     // Reset
     70 
     71     void clear();
     72 
     73     // Accessors
     74 
     75     inline  T&      operator* () const  { return *m_ptr; }
     76     inline  T*      operator-> () const { return m_ptr;  }
     77     inline  T*      get() const         { return m_ptr; }
     78 
     79     // Operators
     80 
     81     COMPARE(==)
     82     COMPARE(!=)
     83     COMPARE(>)
     84     COMPARE(<)
     85     COMPARE(<=)
     86     COMPARE(>=)
     87 
     88 private:    
     89     template<typename Y> friend class sp;
     90     template<typename Y> friend class wp;
     91     void set_pointer(T* ptr);
     92     T* m_ptr;
     93 };
     94 
     95 #undef COMPARE
     96 
     97 template <typename T>
     98 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
     99 
    100 // ---------------------------------------------------------------------------
    101 // No user serviceable parts below here.
    102 
    103 template<typename T>
    104 sp<T>::sp(T* other)
    105 : m_ptr(other)
    106   {
    107     if (other) other->incStrong(this);
    108   }
    109 
    110 template<typename T>
    111 sp<T>::sp(const sp<T>& other)
    112 : m_ptr(other.m_ptr)
    113   {
    114     if (m_ptr) m_ptr->incStrong(this);
    115   }
    116 
    117 template<typename T> template<typename U>
    118 sp<T>::sp(U* other) : m_ptr(other)
    119 {
    120     if (other) ((T*)other)->incStrong(this);
    121 }
    122 
    123 template<typename T> template<typename U>
    124 sp<T>::sp(const sp<U>& other)
    125 : m_ptr(other.m_ptr)
    126   {
    127     if (m_ptr) m_ptr->incStrong(this);
    128   }
    129 
    130 template<typename T>
    131 sp<T>::~sp()
    132 {
    133     if (m_ptr) m_ptr->decStrong(this);
    134 }
    135 
    136 template<typename T>
    137 sp<T>& sp<T>::operator = (const sp<T>& other) {
    138     T* otherPtr(other.m_ptr);
    139     if (otherPtr) otherPtr->incStrong(this);
    140     if (m_ptr) m_ptr->decStrong(this);
    141     m_ptr = otherPtr;
    142     return *this;
    143 }
    144 
    145 template<typename T>
    146 sp<T>& sp<T>::operator = (T* other)
    147 {
    148     if (other) other->incStrong(this);
    149     if (m_ptr) m_ptr->decStrong(this);
    150     m_ptr = other;
    151     return *this;
    152 }
    153 
    154 template<typename T> template<typename U>
    155 sp<T>& sp<T>::operator = (const sp<U>& other)
    156 {
    157     T* otherPtr(other.m_ptr);
    158     if (otherPtr) otherPtr->incStrong(this);
    159     if (m_ptr) m_ptr->decStrong(this);
    160     m_ptr = otherPtr;
    161     return *this;
    162 }
    163 
    164 template<typename T> template<typename U>
    165 sp<T>& sp<T>::operator = (U* other)
    166 {
    167     if (other) ((T*)other)->incStrong(this);
    168     if (m_ptr) m_ptr->decStrong(this);
    169     m_ptr = other;
    170     return *this;
    171 }
    172 
    173 template<typename T>    
    174 void sp<T>::force_set(T* other)
    175 {
    176     other->forceIncStrong(this);
    177     m_ptr = other;
    178 }
    179 
    180 template<typename T>
    181 void sp<T>::clear()
    182 {
    183     if (m_ptr) {
    184         m_ptr->decStrong(this);
    185         m_ptr = 0;
    186     }
    187 }
    188 
    189 template<typename T>
    190 void sp<T>::set_pointer(T* ptr) {
    191     m_ptr = ptr;
    192 }
    193 
    194 template <typename T>
    195 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
    196 {
    197     return printStrongPointer(to, val.get());
    198 }
    199 
    200 }; // namespace android
    201 
    202 // ---------------------------------------------------------------------------
    203 
    204 #endif // ANDROID_STRONG_POINTER_H
    sp
     1 template <typename T>
     2 class sp
     3 {
     4 public:
     5     inline sp() : m_ptr(0) { }
     6     sp(T* other);
     7     sp(const sp<T>& other);
     8     template<typename U> sp(U* other);
     9     template<typename U> sp(const sp<U>& other);
    10     ~sp();
    11     // Assignment
    12     sp& operator = (T* other);
    13     sp& operator = (const sp<T>& other);
    14     template<typename U> sp& operator = (const sp<U>& other);
    15     template<typename U> sp& operator = (U* other);
    16     //! Special optimization for use by ProcessState (and nobody else).
    17     void force_set(T* other);
    18     // Reset
    19     void clear();
    20     // Accessors
    21     inline  T&      operator* () const  { return *m_ptr; }
    22     inline  T*      operator-> () const { return m_ptr;  }
    23     inline  T*      get() const         { return m_ptr; }
    24     // Operators
    25 private:    
    26     template<typename Y> friend class sp;
    27     template<typename Y> friend class wp;
    28     void set_pointer(T* ptr);
    29     T* m_ptr;
    30 };
  • What is ProcessState? libs/binder/ProcessState.cpp,include/binder/ProcessState.h
  •   1 /**
      2  * Copyright (C) 2005 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_TAG "ProcessState"
     18 
     19 #include <cutils/process_name.h>
     20 
     21 #include <binder/ProcessState.h>
     22 
     23 #include <utils/Atomic.h>
     24 #include <binder/BpBinder.h>
     25 #include <binder/IPCThreadState.h>
     26 #include <utils/Log.h>
     27 #include <utils/String8.h>
     28 #include <binder/IServiceManager.h>
     29 #include <utils/String8.h>
     30 #include <utils/threads.h>
     31 
     32 #include <private/binder/binder_module.h>
     33 #include <private/binder/Static.h>
     34 
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <unistd.h>
     40 #include <sys/ioctl.h>
     41 #include <sys/mman.h>
     42 #include <sys/stat.h>
     43 
     44 #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
     45 
     46 
     47 // ---------------------------------------------------------------------------
     48 
     49 namespace android {
     50  
     51 // Global variables
     52 int                 mArgC;
     53 const char* const*  mArgV;
     54 int                 mArgLen;
     55 
     56 class PoolThread : public Thread
     57 {
     58 public:
     59     PoolThread(bool isMain)
     60         : mIsMain(isMain)
     61     {
     62     }
     63     
     64 protected:
     65     virtual bool threadLoop()
     66     {
     67         IPCThreadState::self()->joinThreadPool(mIsMain);
     68         return false;
     69     }
     70     
     71     const bool mIsMain;
     72 };
     73 
     74 sp<ProcessState> ProcessState::self()
     75 {
     76     if (gProcess != NULL) return gProcess;
     77     
     78     AutoMutex _l(gProcessMutex);
     79     if (gProcess == NULL) gProcess = new ProcessState;
     80     return gProcess;
     81 }
     82 
     83 void ProcessState::setContextObject(const sp<IBinder>& object)
     84 {
     85     setContextObject(object, String16("default"));
     86 }
     87 
     88 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
     89 {
     90     return getStrongProxyForHandle(0);
     91 }
     92 
     93 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
     94 {
     95     AutoMutex _l(mLock);
     96     mContexts.add(name, object);
     97 }
     98 
     99 sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
    100 {
    101     mLock.lock();
    102     sp<IBinder> object(
    103         mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
    104     mLock.unlock();
    105     
    106     //printf("Getting context object %s for %p
    ", String8(name).string(), caller.get());
    107     
    108     if (object != NULL) return object;
    109 
    110     // Don't attempt to retrieve contexts if we manage them
    111     if (mManagesContexts) {
    112         LOGE("getContextObject(%s) failed, but we manage the contexts!
    ",
    113             String8(name).string());
    114         return NULL;
    115     }
    116     
    117     IPCThreadState* ipc = IPCThreadState::self();
    118     {
    119         Parcel data, reply;
    120         // no interface token on this magic transaction
    121         data.writeString16(name);
    122         data.writeStrongBinder(caller);
    123         status_t result = ipc->transact(0 /**magic*/, 0, data, &reply, 0);
    124         if (result == NO_ERROR) {
    125             object = reply.readStrongBinder();
    126         }
    127     }
    128     
    129     ipc->flushCommands();
    130     
    131     if (object != NULL) setContextObject(object, name);
    132     return object;
    133 }
    134 
    135 void ProcessState::startThreadPool()
    136 {
    137     AutoMutex _l(mLock);
    138     if (!mThreadPoolStarted) {
    139         mThreadPoolStarted = true;
    140         spawnPooledThread(true);
    141     }
    142 }
    143 
    144 bool ProcessState::isContextManager(void) const
    145 {
    146     return mManagesContexts;
    147 }
    148 
    149 bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
    150 {
    151     if (!mManagesContexts) {
    152         AutoMutex _l(mLock);
    153         mBinderContextCheckFunc = checkFunc;
    154         mBinderContextUserData = userData;
    155 
    156         int dummy = 0;
    157         status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
    158         if (result == 0) {
    159             mManagesContexts = true;
    160         } else if (result == -1) {
    161             mBinderContextCheckFunc = NULL;
    162             mBinderContextUserData = NULL;
    163             LOGE("Binder ioctl to become context manager failed: %s
    ", strerror(errno));
    164         }
    165     }
    166     return mManagesContexts;
    167 }
    168 
    169 ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
    170 {
    171     const size_t N=mHandleToObject.size();
    172     if (N <= (size_t)handle) {
    173         handle_entry e;
    174         e.binder = NULL;
    175         e.refs = NULL;
    176         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
    177         if (err < NO_ERROR) return NULL;
    178     }
    179     return &mHandleToObject.editItemAt(handle);
    180 }
    181 
    182 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    183 {
    184     sp<IBinder> result;
    185 
    186     AutoMutex _l(mLock);
    187 
    188     handle_entry* e = lookupHandleLocked(handle);
    189 
    190     if (e != NULL) {
    191         // We need to create a new BpBinder if there isn't currently one, OR we
    192         // are unable to acquire a weak reference on this current one.  See comment
    193         // in getWeakProxyForHandle() for more info about this.
    194         IBinder* b = e->binder;
    195         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    196             b = new BpBinder(handle); 
    197             e->binder = b;
    198             if (b) e->refs = b->getWeakRefs();
    199             result = b;
    200         } else {
    201             // This little bit of nastyness is to allow us to add a primary
    202             // reference to the remote proxy when this team doesn't have one
    203             // but another team is sending the handle to us.
    204             result.force_set(b);
    205             e->refs->decWeak(this);
    206         }
    207     }
    208 
    209     return result;
    210 }
    211 
    212 wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
    213 {
    214     wp<IBinder> result;
    215 
    216     AutoMutex _l(mLock);
    217 
    218     handle_entry* e = lookupHandleLocked(handle);
    219 
    220     if (e != NULL) {        
    221         // We need to create a new BpBinder if there isn't currently one, OR we
    222         // are unable to acquire a weak reference on this current one.  The
    223         // attemptIncWeak() is safe because we know the BpBinder destructor will always
    224         // call expungeHandle(), which acquires the same lock we are holding now.
    225         // We need to do this because there is a race condition between someone
    226         // releasing a reference on this BpBinder, and a new reference on its handle
    227         // arriving from the driver.
    228         IBinder* b = e->binder;
    229         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    230             b = new BpBinder(handle);
    231             result = b;
    232             e->binder = b;
    233             if (b) e->refs = b->getWeakRefs();
    234         } else {
    235             result = b;
    236             e->refs->decWeak(this);
    237         }
    238     }
    239 
    240     return result;
    241 }
    242 
    243 void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
    244 {
    245     AutoMutex _l(mLock);
    246     
    247     handle_entry* e = lookupHandleLocked(handle);
    248 
    249     // This handle may have already been replaced with a new BpBinder
    250     // (if someone failed the AttemptIncWeak() above); we don't want
    251     // to overwrite it.
    252     if (e && e->binder == binder) e->binder = NULL;
    253 }
    254 
    255 void ProcessState::setArgs(int argc, const char* const argv[])
    256 {
    257     mArgC = argc;
    258     mArgV = (const char **)argv;
    259 
    260     mArgLen = 0;
    261     for (int i=0; i<argc; i++) {
    262         mArgLen += strlen(argv[i]) + 1;
    263     }
    264     mArgLen--;
    265 }
    266 
    267 int ProcessState::getArgC() const
    268 {
    269     return mArgC;
    270 }
    271 
    272 const char* const* ProcessState::getArgV() const
    273 {
    274     return mArgV;
    275 }
    276 
    277 void ProcessState::setArgV0(const char* txt)
    278 {
    279     if (mArgV != NULL) {
    280         strncpy((char*)mArgV[0], txt, mArgLen);
    281         set_process_name(txt);
    282     }
    283 }
    284 
    285 void ProcessState::spawnPooledThread(bool isMain)
    286 {
    287     if (mThreadPoolStarted) {
    288         int32_t s = android_atomic_add(1, &mThreadPoolSeq);
    289         char buf[32];
    290         sprintf(buf, "Binder Thread #%d", s);
    291         LOGV("Spawning new pooled thread, name=%s
    ", buf);
    292         sp<Thread> t = new PoolThread(isMain);
    293         t->run(buf);
    294     }
    295 }
    296 
    297 static int open_driver()
    298 {
    299     int fd = open("/dev/binder", O_RDWR);
    300     if (fd >= 0) {
    301         fcntl(fd, F_SETFD, FD_CLOEXEC);
    302         int vers;
    303         status_t result = ioctl(fd, BINDER_VERSION, &vers);
    304         if (result == -1) {
    305             LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
    306             close(fd);
    307             fd = -1;
    308         }
    309         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
    310             LOGE("Binder driver protocol does not match user space protocol!");
    311             close(fd);
    312             fd = -1;
    313         }
    314         size_t maxThreads = 15;
    315         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
    316         if (result == -1) {
    317             LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
    318         }
    319     } else {
    320         LOGW("Opening '/dev/binder' failed: %s
    ", strerror(errno));
    321     }
    322     return fd;
    323 }
    324 
    325 ProcessState::ProcessState()
    326     : mDriverFD(open_driver())
    327     , mVMStart(MAP_FAILED)
    328     , mManagesContexts(false)
    329     , mBinderContextCheckFunc(NULL)
    330     , mBinderContextUserData(NULL)
    331     , mThreadPoolStarted(false)
    332     , mThreadPoolSeq(1)
    333 {
    334     if (mDriverFD >= 0) {
    335         // XXX Ideally, there should be a specific define for whether we
    336         // have mmap (or whether we could possibly have the kernel module
    337         // availabla).
    338 #if !defined(HAVE_WIN32_IPC)
    339         // mmap the binder, providing a chunk of virtual address space to receive transactions.
    340         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    341         if (mVMStart == MAP_FAILED) {
    342             // *sigh*
    343             LOGE("Using /dev/binder failed: unable to mmap transaction memory.
    ");
    344             close(mDriverFD);
    345             mDriverFD = -1;
    346         }
    347 #else
    348         mDriverFD = -1;
    349 #endif
    350     }
    351 
    352     LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
    353 }
    354 
    355 ProcessState::~ProcessState()
    356 {
    357 }
    358         
    359 }; // namespace android
    ProcessState
    sp<ProcessState> ProcessState::self()
    {
        if (gProcess != NULL) 
              return gProcess;    
        AutoMutex _l(gProcessMutex);
        if (gProcess == NULL) 
             gProcess = new ProcessState;
        return gProcess;
    }
     1 #ifndef ANDROID_PROCESS_STATE_H
     2 #define ANDROID_PROCESS_STATE_H
     3 
     4 #include <binder/IBinder.h>
     5 #include <utils/KeyedVector.h>
     6 #include <utils/String8.h>
     7 #include <utils/String16.h>
     8 
     9 #include <utils/threads.h>
    10 namespace android {
    11 // Global variables
    12 extern int                 mArgC;
    13 extern const char* const*  mArgV;
    14 extern int                 mArgLen;
    15 class IPCThreadState;
    16 class ProcessState : public virtual RefBase
    17 {
    18 public:
    19     static sp<ProcessState>  self();//Singleton
    20     void   setContextObject(const sp<IBinder>& object);
    21     sp<IBinder>  getContextObject(const sp<IBinder>& caller);        
    22     void  setContextObject(const sp<IBinder>& object,const String16& name);
    23     sp<IBinder> getContextObject(const String16& name,const sp<IBinder>& caller);
    24     void  startThreadPool();                        
    25     typedef bool (*context_check_func)(const String16& name,
    26                                        const sp<IBinder>& caller,
    27                                        void* userData);        
    28     bool  isContextManager(void) const;
    29     bool  becomeContextManager(context_check_func checkFunc,void* userData);
    30     sp<IBinder> getStrongProxyForHandle(int32_t handle);
    31     wp<IBinder> getWeakProxyForHandle(int32_t handle);
    32     void  expungeHandle(int32_t handle, IBinder* binder);    
    33     void  setArgs(int argc, const char* const argv[]);
    34     int getArgC() const;
    35     const char* const*  getArgV() const;    
    36     void  setArgV0(const char* txt);    
    37     void  spawnPooledThread(bool isMain);            
    38 private:
    39     friend class IPCThreadState;    
    40     ProcessState();
    41     ~ProcessState();
    42     ProcessState(const ProcessState& o);
    43     ProcessState& operator=(const ProcessState& o);    
    44     struct handle_entry {
    45         IBinder* binder;
    46         RefBase::weakref_type* refs;
    47     };    
    48     handle_entry*  lookupHandleLocked(int32_t handle);    
    49     int   mDriverFD;
    50     void* mVMStart;        
    51     mutable Mutex               mLock;  // protects everything below.        
    52     Vector<handle_entry> mHandleToObject;
    53     bool                 mManagesContexts;
    54     context_check_func   mBinderContextCheckFunc;
    55     void*                mBinderContextUserData;        
    56     KeyedVector<String16, sp<IBinder> >   mContexts;
    57     String8             mRootDir;
    58     bool                mThreadPoolStarted;
    59     volatile int32_t            mThreadPoolSeq;
    60 };
      1 /**
      2  * Copyright (C) 2005 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_TAG "RefBase"
     18 
     19 #include <utils/RefBase.h>
     20 
     21 #include <utils/Atomic.h>
     22 #include <utils/CallStack.h>
     23 #include <utils/Log.h>
     24 #include <utils/threads.h>
     25 #include <utils/TextOutput.h>
     26 
     27 #include <stdlib.h>
     28 #include <stdio.h>
     29 #include <typeinfo>
     30 #include <sys/types.h>
     31 #include <sys/stat.h>
     32 #include <fcntl.h>
     33 #include <unistd.h>
     34 
     35 // compile with refcounting debugging enabled
     36 #define DEBUG_REFS                      0
     37 #define DEBUG_REFS_FATAL_SANITY_CHECKS  0
     38 #define DEBUG_REFS_ENABLED_BY_DEFAULT   1
     39 #define DEBUG_REFS_CALLSTACK_ENABLED    1
     40 
     41 // log all reference counting operations
     42 #define PRINT_REFS                      0
     43 
     44 // ---------------------------------------------------------------------------
     45 
     46 namespace android {
     47 
     48 #define INITIAL_STRONG_VALUE (1<<28)
     49 
     50 // ---------------------------------------------------------------------------
     51 
     52 class RefBase::weakref_impl : public RefBase::weakref_type
     53 {
     54 public:
     55     volatile int32_t    mStrong;
     56     volatile int32_t    mWeak;
     57     RefBase* const      mBase;
     58     volatile int32_t    mFlags;
     59 
     60 #if !DEBUG_REFS
     61 
     62     weakref_impl(RefBase* base)
     63         : mStrong(INITIAL_STRONG_VALUE)
     64         , mWeak(0)
     65         , mBase(base)
     66         , mFlags(0)
     67     {
     68     }
     69 
     70     void addStrongRef(const void* /**id*/) { }
     71     void removeStrongRef(const void* /**id*/) { }
     72     void renameStrongRefId(const void* /**old_id*/, const void* /**new_id*/) { }
     73     void addWeakRef(const void* /**id*/) { }
     74     void removeWeakRef(const void* /**id*/) { }
     75     void renameWeakRefId(const void* /**old_id*/, const void* /**new_id*/) { }
     76     void printRefs() const { }
     77     void trackMe(bool, bool) { }
     78 
     79 #else
     80 
     81     weakref_impl(RefBase* base)
     82         : mStrong(INITIAL_STRONG_VALUE)
     83         , mWeak(0)
     84         , mBase(base)
     85         , mFlags(0)
     86         , mStrongRefs(NULL)
     87         , mWeakRefs(NULL)
     88         , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
     89         , mRetain(false)
     90     {
     91     }
     92     
     93     ~weakref_impl()
     94     {
     95         bool dumpStack = false;
     96         if (!mRetain && mStrongRefs != NULL) {
     97             dumpStack = true;
     98 #if DEBUG_REFS_FATAL_SANITY_CHECKS
     99             LOG_ALWAYS_FATAL("Strong references remain!");
    100 #else
    101             LOGE("Strong references remain:");
    102 #endif
    103             ref_entry* refs = mStrongRefs;
    104             while (refs) {
    105                 char inc = refs->ref >= 0 ? '+' : '-';
    106                 LOGD("	%c ID %p (ref %d):", inc, refs->id, refs->ref);
    107 #if DEBUG_REFS_CALLSTACK_ENABLED
    108                 refs->stack.dump();
    109 #endif
    110                 refs = refs->next;
    111             }
    112         }
    113 
    114         if (!mRetain && mWeakRefs != NULL) {
    115             dumpStack = true;
    116 #if DEBUG_REFS_FATAL_SANITY_CHECKS
    117             LOG_ALWAYS_FATAL("Weak references remain:");
    118 #else
    119             LOGE("Weak references remain!");
    120 #endif
    121             ref_entry* refs = mWeakRefs;
    122             while (refs) {
    123                 char inc = refs->ref >= 0 ? '+' : '-';
    124                 LOGD("	%c ID %p (ref %d):", inc, refs->id, refs->ref);
    125 #if DEBUG_REFS_CALLSTACK_ENABLED
    126                 refs->stack.dump();
    127 #endif
    128                 refs = refs->next;
    129             }
    130         }
    131         if (dumpStack) {
    132             LOGE("above errors at:");
    133             CallStack stack;
    134             stack.update();
    135             stack.dump();
    136         }
    137     }
    138 
    139     void addStrongRef(const void* id) {
    140         //LOGD_IF(mTrackEnabled,
    141         //        "addStrongRef: RefBase=%p, id=%p", mBase, id);
    142         addRef(&mStrongRefs, id, mStrong);
    143     }
    144 
    145     void removeStrongRef(const void* id) {
    146         //LOGD_IF(mTrackEnabled,
    147         //        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
    148         if (!mRetain) {
    149             removeRef(&mStrongRefs, id);
    150         } else {
    151             addRef(&mStrongRefs, id, -mStrong);
    152         }
    153     }
    154 
    155     void renameStrongRefId(const void* old_id, const void* new_id) {
    156         //LOGD_IF(mTrackEnabled,
    157         //        "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
    158         //        mBase, old_id, new_id);
    159         renameRefsId(mStrongRefs, old_id, new_id);
    160     }
    161 
    162     void addWeakRef(const void* id) {
    163         addRef(&mWeakRefs, id, mWeak);
    164     }
    165 
    166     void removeWeakRef(const void* id) {
    167         if (!mRetain) {
    168             removeRef(&mWeakRefs, id);
    169         } else {
    170             addRef(&mWeakRefs, id, -mWeak);
    171         }
    172     }
    173 
    174     void renameWeakRefId(const void* old_id, const void* new_id) {
    175         renameRefsId(mWeakRefs, old_id, new_id);
    176     }
    177 
    178     void trackMe(bool track, bool retain)
    179     { 
    180         mTrackEnabled = track;
    181         mRetain = retain;
    182     }
    183 
    184     void printRefs() const
    185     {
    186         String8 text;
    187 
    188         {
    189             Mutex::Autolock _l(mMutex);
    190             char buf[128];
    191             sprintf(buf, "Strong references on RefBase %p (weakref_type %p):
    ", mBase, this);
    192             text.append(buf);
    193             printRefsLocked(&text, mStrongRefs);
    194             sprintf(buf, "Weak references on RefBase %p (weakref_type %p):
    ", mBase, this);
    195             text.append(buf);
    196             printRefsLocked(&text, mWeakRefs);
    197         }
    198 
    199         {
    200             char name[100];
    201             snprintf(name, 100, "/data/%p.stack", this);
    202             int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
    203             if (rc >= 0) {
    204                 write(rc, text.string(), text.length());
    205                 close(rc);
    206                 LOGD("STACK TRACE for %p saved in %s", this, name);
    207             }
    208             else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
    209                       name, strerror(errno));
    210         }
    211     }
    212 
    213 private:
    214     struct ref_entry
    215     {
    216         ref_entry* next;
    217         const void* id;
    218 #if DEBUG_REFS_CALLSTACK_ENABLED
    219         CallStack stack;
    220 #endif
    221         int32_t ref;
    222     };
    223 
    224     void addRef(ref_entry** refs, const void* id, int32_t mRef)
    225     {
    226         if (mTrackEnabled) {
    227             AutoMutex _l(mMutex);
    228 
    229             ref_entry* ref = new ref_entry;
    230             // Reference count at the time of the snapshot, but before the
    231             // update.  Positive value means we increment, negative--we
    232             // decrement the reference count.
    233             ref->ref = mRef;
    234             ref->id = id;
    235 #if DEBUG_REFS_CALLSTACK_ENABLED
    236             ref->stack.update(2);
    237 #endif
    238             ref->next = *refs;
    239             *refs = ref;
    240         }
    241     }
    242 
    243     void removeRef(ref_entry** refs, const void* id)
    244     {
    245         if (mTrackEnabled) {
    246             AutoMutex _l(mMutex);
    247             
    248             ref_entry* const head = *refs;
    249             ref_entry* ref = head;
    250             while (ref != NULL) {
    251                 if (ref->id == id) {
    252                     *refs = ref->next;
    253                     delete ref;
    254                     return;
    255                 }
    256                 refs = &ref->next;
    257                 ref = *refs;
    258             }
    259 
    260 #if DEBUG_REFS_FATAL_SANITY_CHECKS
    261             LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
    262                     "(weakref_type %p) that doesn't exist!",
    263                     id, mBase, this);
    264 #endif
    265 
    266             LOGE("RefBase: removing id %p on RefBase %p"
    267                     "(weakref_type %p) that doesn't exist!",
    268                     id, mBase, this);
    269 
    270             ref = head;
    271             while (ref) {
    272                 char inc = ref->ref >= 0 ? '+' : '-';
    273                 LOGD("	%c ID %p (ref %d):", inc, ref->id, ref->ref);
    274                 ref = ref->next;
    275             }
    276 
    277             CallStack stack;
    278             stack.update();
    279             stack.dump();
    280         }
    281     }
    282 
    283     void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
    284     {
    285         if (mTrackEnabled) {
    286             AutoMutex _l(mMutex);
    287             ref_entry* ref = r;
    288             while (ref != NULL) {
    289                 if (ref->id == old_id) {
    290                     ref->id = new_id;
    291                 }
    292                 ref = ref->next;
    293             }
    294         }
    295     }
    296 
    297     void printRefsLocked(String8* out, const ref_entry* refs) const
    298     {
    299         char buf[128];
    300         while (refs) {
    301             char inc = refs->ref >= 0 ? '+' : '-';
    302             sprintf(buf, "	%c ID %p (ref %d):
    ", 
    303                     inc, refs->id, refs->ref);
    304             out->append(buf);
    305 #if DEBUG_REFS_CALLSTACK_ENABLED
    306             out->append(refs->stack.toString("		"));
    307 #else
    308             out->append("		(call stacks disabled)");
    309 #endif
    310             refs = refs->next;
    311         }
    312     }
    313 
    314     mutable Mutex mMutex;
    315     ref_entry* mStrongRefs;
    316     ref_entry* mWeakRefs;
    317 
    318     bool mTrackEnabled;
    319     // Collect stack traces on addref and removeref, instead of deleting the stack references
    320     // on removeref that match the address ones.
    321     bool mRetain;
    322 
    323 #endif
    324 };
    325 
    326 // ---------------------------------------------------------------------------
    327 
    328 void RefBase::incStrong(const void* id) const
    329 {
    330     weakref_impl* const refs = mRefs;
    331     refs->incWeak(id);
    332     
    333     refs->addStrongRef(id);
    334     const int32_t c = android_atomic_inc(&refs->mStrong);
    335     LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
    336 #if PRINT_REFS
    337     LOGD("incStrong of %p from %p: cnt=%d
    ", this, id, c);
    338 #endif
    339     if (c != INITIAL_STRONG_VALUE)  {
    340         return;
    341     }
    342 
    343     android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
    344     refs->mBase->onFirstRef();
    345 }
    346 
    347 void RefBase::decStrong(const void* id) const
    348 {
    349     weakref_impl* const refs = mRefs;
    350     refs->removeStrongRef(id);
    351     const int32_t c = android_atomic_dec(&refs->mStrong);
    352 #if PRINT_REFS
    353     LOGD("decStrong of %p from %p: cnt=%d
    ", this, id, c);
    354 #endif
    355     LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
    356     if (c == 1) {
    357         refs->mBase->onLastStrongRef(id);
    358         if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
    359             delete this;
    360         }
    361     }
    362     refs->decWeak(id);
    363 }
    364 
    365 void RefBase::forceIncStrong(const void* id) const
    366 {
    367     weakref_impl* const refs = mRefs;
    368     refs->incWeak(id);
    369     
    370     refs->addStrongRef(id);
    371     const int32_t c = android_atomic_inc(&refs->mStrong);
    372     LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
    373                refs);
    374 #if PRINT_REFS
    375     LOGD("forceIncStrong of %p from %p: cnt=%d
    ", this, id, c);
    376 #endif
    377 
    378     switch (c) {
    379     case INITIAL_STRONG_VALUE:
    380         android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
    381         // fall through...
    382     case 0:
    383         refs->mBase->onFirstRef();
    384     }
    385 }
    386 
    387 int32_t RefBase::getStrongCount() const
    388 {
    389     return mRefs->mStrong;
    390 }
    391 
    392 RefBase* RefBase::weakref_type::refBase() const
    393 {
    394     return static_cast<const weakref_impl*>(this)->mBase;
    395 }
    396 
    397 void RefBase::weakref_type::incWeak(const void* id)
    398 {
    399     weakref_impl* const impl = static_cast<weakref_impl*>(this);
    400     impl->addWeakRef(id);
    401     const int32_t c = android_atomic_inc(&impl->mWeak);
    402     LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
    403 }
    404 
    405 
    406 void RefBase::weakref_type::decWeak(const void* id)
    407 {
    408     weakref_impl* const impl = static_cast<weakref_impl*>(this);
    409     impl->removeWeakRef(id);
    410     const int32_t c = android_atomic_dec(&impl->mWeak);
    411     LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    412     if (c != 1) return;
    413 
    414     if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
    415         // This is the regular lifetime case. The object is destroyed
    416         // when the last strong reference goes away. Since weakref_impl
    417         // outlive the object, it is not destroyed in the dtor, and
    418         // we'll have to do it here.
    419         if (impl->mStrong == INITIAL_STRONG_VALUE) {
    420             // Special case: we never had a strong reference, so we need to
    421             // destroy the object now.
    422             delete impl->mBase;
    423         } else {
    424             // LOGV("Freeing refs %p of old RefBase %p
    ", this, impl->mBase);
    425             delete impl;
    426         }
    427     } else {
    428         // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
    429         impl->mBase->onLastWeakRef(id);
    430         if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
    431             // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
    432             // is gone, we can destroy the object.
    433             delete impl->mBase;
    434         }
    435     }
    436 }
    437 
    438 bool RefBase::weakref_type::attemptIncStrong(const void* id)
    439 {
    440     incWeak(id);
    441     
    442     weakref_impl* const impl = static_cast<weakref_impl*>(this);
    443     
    444     int32_t curCount = impl->mStrong;
    445     LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
    446                this);
    447     while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
    448         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
    449             break;
    450         }
    451         curCount = impl->mStrong;
    452     }
    453     
    454     if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
    455         bool allow;
    456         if (curCount == INITIAL_STRONG_VALUE) {
    457             // Attempting to acquire first strong reference...  this is allowed
    458             // if the object does NOT have a longer lifetime (meaning the
    459             // implementation doesn't need to see this), or if the implementation
    460             // allows it to happen.
    461             allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
    462                   || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
    463         } else {
    464             // Attempting to revive the object...  this is allowed
    465             // if the object DOES have a longer lifetime (so we can safely
    466             // call the object with only a weak ref) and the implementation
    467             // allows it to happen.
    468             allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
    469                   && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
    470         }
    471         if (!allow) {
    472             decWeak(id);
    473             return false;
    474         }
    475         curCount = android_atomic_inc(&impl->mStrong);
    476 
    477         // If the strong reference count has already been incremented by
    478         // someone else, the implementor of onIncStrongAttempted() is holding
    479         // an unneeded reference.  So call onLastStrongRef() here to remove it.
    480         // (No, this is not pretty.)  Note that we MUST NOT do this if we
    481         // are in fact acquiring the first reference.
    482         if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
    483             impl->mBase->onLastStrongRef(id);
    484         }
    485     }
    486     
    487     impl->addStrongRef(id);
    488 
    489 #if PRINT_REFS
    490     LOGD("attemptIncStrong of %p from %p: cnt=%d
    ", this, id, curCount);
    491 #endif
    492 
    493     if (curCount == INITIAL_STRONG_VALUE) {
    494         android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
    495         impl->mBase->onFirstRef();
    496     }
    497     
    498     return true;
    499 }
    500 
    501 bool RefBase::weakref_type::attemptIncWeak(const void* id)
    502 {
    503     weakref_impl* const impl = static_cast<weakref_impl*>(this);
    504 
    505     int32_t curCount = impl->mWeak;
    506     LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
    507                this);
    508     while (curCount > 0) {
    509         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
    510             break;
    511         }
    512         curCount = impl->mWeak;
    513     }
    514 
    515     if (curCount > 0) {
    516         impl->addWeakRef(id);
    517     }
    518 
    519     return curCount > 0;
    520 }
    521 
    522 int32_t RefBase::weakref_type::getWeakCount() const
    523 {
    524     return static_cast<const weakref_impl*>(this)->mWeak;
    525 }
    526 
    527 void RefBase::weakref_type::printRefs() const
    528 {
    529     static_cast<const weakref_impl*>(this)->printRefs();
    530 }
    531 
    532 void RefBase::weakref_type::trackMe(bool enable, bool retain)
    533 {
    534     static_cast<weakref_impl*>(this)->trackMe(enable, retain);
    535 }
    536 
    537 RefBase::weakref_type* RefBase::createWeak(const void* id) const
    538 {
    539     mRefs->incWeak(id);
    540     return mRefs;
    541 }
    542 
    543 RefBase::weakref_type* RefBase::getWeakRefs() const
    544 {
    545     return mRefs;
    546 }
    547 
    548 RefBase::RefBase()
    549     : mRefs(new weakref_impl(this))
    550 {
    551 }
    552 
    553 RefBase::~RefBase()
    554 {
    555     if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
    556         // we never acquired a strong (and/or weak) reference on this object.
    557         delete mRefs;
    558     } else {
    559         // life-time of this object is extended to WEAK or FOREVER, in
    560         // which case weakref_impl doesn't out-live the object and we
    561         // can free it now.
    562         if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
    563             // It's possible that the weak count is not 0 if the object
    564             // re-acquired a weak reference in its destructor
    565             if (mRefs->mWeak == 0) {
    566                 delete mRefs;
    567             }
    568         }
    569     }
    570     // for debugging purposes, clear this.
    571     const_cast<weakref_impl*&>(mRefs) = NULL;
    572 }
    573 
    574 void RefBase::extendObjectLifetime(int32_t mode)
    575 {
    576     android_atomic_or(mode, &mRefs->mFlags);
    577 }
    578 
    579 void RefBase::onFirstRef()
    580 {
    581 }
    582 
    583 void RefBase::onLastStrongRef(const void* /**id*/)
    584 {
    585 }
    586 
    587 bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
    588 {
    589     return (flags&FIRST_INC_STRONG) ? true : false;
    590 }
    591 
    592 void RefBase::onLastWeakRef(const void* /**id*/)
    593 {
    594 }
    595 
    596 // ---------------------------------------------------------------------------
    597 
    598 void RefBase::moveReferences(void* dst, void const* src, size_t n,
    599         const ReferenceConverterBase& caster)
    600 {
    601 #if DEBUG_REFS
    602     const size_t itemSize = caster.getReferenceTypeSize();
    603     for (size_t i=0 ; i<n ; i++) {
    604         void*       d = reinterpret_cast<void      *>(intptr_t(dst) + i*itemSize);
    605         void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
    606         RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
    607         ref->mRefs->renameStrongRefId(s, d);
    608         ref->mRefs->renameWeakRefId(s, d);
    609     }
    610 #endif
    611 }
    612 
    613 // ---------------------------------------------------------------------------
    614 
    615 TextOutput& printStrongPointer(TextOutput& to, const void* val)
    616 {
    617     to << "sp<>(" << val << ")";
    618     return to;
    619 }
    620 
    621 TextOutput& printWeakPointer(TextOutput& to, const void* val)
    622 {
    623     to << "wp<>(" << val << ")";
    624     return to;
    625 }
    626 
    627 
    628 }; // namespace android
    RefBase
       1 /**
       2  * Copyright (C) 2005 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_TAG "IPCThreadState"
      18 
      19 #include <binder/IPCThreadState.h>
      20 
      21 #include <binder/Binder.h>
      22 #include <binder/BpBinder.h>
      23 #include <cutils/sched_policy.h>
      24 #include <utils/Debug.h>
      25 #include <utils/Log.h>
      26 #include <utils/TextOutput.h>
      27 #include <utils/threads.h>
      28 
      29 #include <private/binder/binder_module.h>
      30 #include <private/binder/Static.h>
      31 
      32 #include <sys/ioctl.h>
      33 #include <signal.h>
      34 #include <errno.h>
      35 #include <stdio.h>
      36 #include <unistd.h>
      37 
      38 #ifdef HAVE_PTHREADS
      39 #include <pthread.h>
      40 #include <sched.h>
      41 #include <sys/resource.h>
      42 #endif
      43 #ifdef HAVE_WIN32_THREADS
      44 #include <windows.h>
      45 #endif
      46 
      47 
      48 #if LOG_NDEBUG
      49 
      50 #define IF_LOG_TRANSACTIONS() if (false)
      51 #define IF_LOG_COMMANDS() if (false)
      52 #define LOG_REMOTEREFS(...) 
      53 #define IF_LOG_REMOTEREFS() if (false)
      54 #define LOG_THREADPOOL(...) 
      55 #define LOG_ONEWAY(...) 
      56 
      57 #else
      58 
      59 #define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
      60 #define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
      61 #define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
      62 #define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
      63 #define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
      64 #define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
      65 
      66 #endif
      67 
      68 // ---------------------------------------------------------------------------
      69 
      70 namespace android {
      71 
      72 static const char* getReturnString(size_t idx);
      73 static const char* getCommandString(size_t idx);
      74 static const void* printReturnCommand(TextOutput& out, const void* _cmd);
      75 static const void* printCommand(TextOutput& out, const void* _cmd);
      76 
      77 // This will result in a missing symbol failure if the IF_LOG_COMMANDS()
      78 // conditionals don't get stripped...  but that is probably what we want.
      79 #if !LOG_NDEBUG
      80 static const char *kReturnStrings[] = {
      81     "BR_ERROR",
      82     "BR_OK",
      83     "BR_TRANSACTION",
      84     "BR_REPLY",
      85     "BR_ACQUIRE_RESULT",
      86     "BR_DEAD_REPLY",
      87     "BR_TRANSACTION_COMPLETE",
      88     "BR_INCREFS",
      89     "BR_ACQUIRE",
      90     "BR_RELEASE",
      91     "BR_DECREFS",
      92     "BR_ATTEMPT_ACQUIRE",
      93     "BR_NOOP",
      94     "BR_SPAWN_LOOPER",
      95     "BR_FINISHED",
      96     "BR_DEAD_BINDER",
      97     "BR_CLEAR_DEATH_NOTIFICATION_DONE",
      98     "BR_FAILED_REPLY"
      99 };
     100 
     101 static const char *kCommandStrings[] = {
     102     "BC_TRANSACTION",
     103     "BC_REPLY",
     104     "BC_ACQUIRE_RESULT",
     105     "BC_FREE_BUFFER",
     106     "BC_INCREFS",
     107     "BC_ACQUIRE",
     108     "BC_RELEASE",
     109     "BC_DECREFS",
     110     "BC_INCREFS_DONE",
     111     "BC_ACQUIRE_DONE",
     112     "BC_ATTEMPT_ACQUIRE",
     113     "BC_REGISTER_LOOPER",
     114     "BC_ENTER_LOOPER",
     115     "BC_EXIT_LOOPER",
     116     "BC_REQUEST_DEATH_NOTIFICATION",
     117     "BC_CLEAR_DEATH_NOTIFICATION",
     118     "BC_DEAD_BINDER_DONE"
     119 };
     120 
     121 static const char* getReturnString(size_t idx)
     122 {
     123     if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
     124         return kReturnStrings[idx];
     125     else
     126         return "unknown";
     127 }
     128 
     129 static const char* getCommandString(size_t idx)
     130 {
     131     if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
     132         return kCommandStrings[idx];
     133     else
     134         return "unknown";
     135 }
     136 
     137 static const void* printBinderTransactionData(TextOutput& out, const void* data)
     138 {
     139     const binder_transaction_data* btd =
     140         (const binder_transaction_data*)data;
     141     if (btd->target.handle < 1024) {
     142         /** want to print descriptors in decimal; guess based on value */
     143         out << "target.desc=" << btd->target.handle;
     144     } else {
     145         out << "target.ptr=" << btd->target.ptr;
     146     }
     147     out << " (cookie " << btd->cookie << ")" << endl
     148         << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
     149         << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
     150         << " bytes)" << endl
     151         << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
     152         << " bytes)";
     153     return btd+1;
     154 }
     155 
     156 static const void* printReturnCommand(TextOutput& out, const void* _cmd)
     157 {
     158     static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
     159     const int32_t* cmd = (const int32_t*)_cmd;
     160     int32_t code = *cmd++;
     161     size_t cmdIndex = code & 0xff;
     162     if (code == (int32_t) BR_ERROR) {
     163         out << "BR_ERROR: " << (void*)(*cmd++) << endl;
     164         return cmd;
     165     } else if (cmdIndex >= N) {
     166         out << "Unknown reply: " << code << endl;
     167         return cmd;
     168     }
     169     out << kReturnStrings[cmdIndex];
     170     
     171     switch (code) {
     172         case BR_TRANSACTION:
     173         case BR_REPLY: {
     174             out << ": " << indent;
     175             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
     176             out << dedent;
     177         } break;
     178         
     179         case BR_ACQUIRE_RESULT: {
     180             const int32_t res = *cmd++;
     181             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
     182         } break;
     183         
     184         case BR_INCREFS:
     185         case BR_ACQUIRE:
     186         case BR_RELEASE:
     187         case BR_DECREFS: {
     188             const int32_t b = *cmd++;
     189             const int32_t c = *cmd++;
     190             out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
     191         } break;
     192     
     193         case BR_ATTEMPT_ACQUIRE: {
     194             const int32_t p = *cmd++;
     195             const int32_t b = *cmd++;
     196             const int32_t c = *cmd++;
     197             out << ": target=" << (void*)b << " (cookie " << (void*)c
     198                 << "), pri=" << p;
     199         } break;
     200 
     201         case BR_DEAD_BINDER:
     202         case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
     203             const int32_t c = *cmd++;
     204             out << ": death cookie " << (void*)c;
     205         } break;
     206 
     207         default:
     208             // no details to show for: BR_OK, BR_DEAD_REPLY,
     209             // BR_TRANSACTION_COMPLETE, BR_FINISHED
     210             break;
     211     }
     212     
     213     out << endl;
     214     return cmd;
     215 }
     216 
     217 static const void* printCommand(TextOutput& out, const void* _cmd)
     218 {
     219     static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
     220     const int32_t* cmd = (const int32_t*)_cmd;
     221     int32_t code = *cmd++;
     222     size_t cmdIndex = code & 0xff;
     223 
     224     if (cmdIndex >= N) {
     225         out << "Unknown command: " << code << endl;
     226         return cmd;
     227     }
     228     out << kCommandStrings[cmdIndex];
     229 
     230     switch (code) {
     231         case BC_TRANSACTION:
     232         case BC_REPLY: {
     233             out << ": " << indent;
     234             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
     235             out << dedent;
     236         } break;
     237         
     238         case BC_ACQUIRE_RESULT: {
     239             const int32_t res = *cmd++;
     240             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
     241         } break;
     242         
     243         case BC_FREE_BUFFER: {
     244             const int32_t buf = *cmd++;
     245             out << ": buffer=" << (void*)buf;
     246         } break;
     247         
     248         case BC_INCREFS:
     249         case BC_ACQUIRE:
     250         case BC_RELEASE:
     251         case BC_DECREFS: {
     252             const int32_t d = *cmd++;
     253             out << ": desc=" << d;
     254         } break;
     255     
     256         case BC_INCREFS_DONE:
     257         case BC_ACQUIRE_DONE: {
     258             const int32_t b = *cmd++;
     259             const int32_t c = *cmd++;
     260             out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
     261         } break;
     262         
     263         case BC_ATTEMPT_ACQUIRE: {
     264             const int32_t p = *cmd++;
     265             const int32_t d = *cmd++;
     266             out << ": desc=" << d << ", pri=" << p;
     267         } break;
     268         
     269         case BC_REQUEST_DEATH_NOTIFICATION:
     270         case BC_CLEAR_DEATH_NOTIFICATION: {
     271             const int32_t h = *cmd++;
     272             const int32_t c = *cmd++;
     273             out << ": handle=" << h << " (death cookie " << (void*)c << ")";
     274         } break;
     275 
     276         case BC_DEAD_BINDER_DONE: {
     277             const int32_t c = *cmd++;
     278             out << ": death cookie " << (void*)c;
     279         } break;
     280 
     281         default:
     282             // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
     283             // BC_EXIT_LOOPER
     284             break;
     285     }
     286     
     287     out << endl;
     288     return cmd;
     289 }
     290 #endif
     291 
     292 static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
     293 static bool gHaveTLS = false;
     294 static pthread_key_t gTLS = 0;
     295 static bool gShutdown = false;
     296 static bool gDisableBackgroundScheduling = false;
     297 
     298 IPCThreadState* IPCThreadState::self()
     299 {
     300     if (gHaveTLS) {
     301 restart:
     302         const pthread_key_t k = gTLS;
     303         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
     304         if (st) return st;
     305         return new IPCThreadState;
     306     }
     307     
     308     if (gShutdown) return NULL;
     309     
     310     pthread_mutex_lock(&gTLSMutex);
     311     if (!gHaveTLS) {
     312         if (pthread_key_create(&gTLS, threadDestructor) != 0) {
     313             pthread_mutex_unlock(&gTLSMutex);
     314             return NULL;
     315         }
     316         gHaveTLS = true;
     317     }
     318     pthread_mutex_unlock(&gTLSMutex);
     319     goto restart;
     320 }
     321 
     322 IPCThreadState* IPCThreadState::selfOrNull()
     323 {
     324     if (gHaveTLS) {
     325         const pthread_key_t k = gTLS;
     326         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
     327         return st;
     328     }
     329     return NULL;
     330 }
     331 
     332 void IPCThreadState::shutdown()
     333 {
     334     gShutdown = true;
     335     
     336     if (gHaveTLS) {
     337         // XXX Need to wait for all thread pool threads to exit!
     338         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
     339         if (st) {
     340             delete st;
     341             pthread_setspecific(gTLS, NULL);
     342         }
     343         gHaveTLS = false;
     344     }
     345 }
     346 
     347 void IPCThreadState::disableBackgroundScheduling(bool disable)
     348 {
     349     gDisableBackgroundScheduling = disable;
     350 }
     351 
     352 sp<ProcessState> IPCThreadState::process()
     353 {
     354     return mProcess;
     355 }
     356 
     357 status_t IPCThreadState::clearLastError()
     358 {
     359     const status_t err = mLastError;
     360     mLastError = NO_ERROR;
     361     return err;
     362 }
     363 
     364 int IPCThreadState::getCallingPid()
     365 {
     366     return mCallingPid;
     367 }
     368 
     369 int IPCThreadState::getCallingUid()
     370 {
     371     return mCallingUid;
     372 }
     373 
     374 int64_t IPCThreadState::clearCallingIdentity()
     375 {
     376     int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
     377     clearCaller();
     378     return token;
     379 }
     380 
     381 void IPCThreadState::setStrictModePolicy(int32_t policy)
     382 {
     383     mStrictModePolicy = policy;
     384 }
     385 
     386 int32_t IPCThreadState::getStrictModePolicy() const
     387 {
     388     return mStrictModePolicy;
     389 }
     390 
     391 void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
     392 {
     393     mLastTransactionBinderFlags = flags;
     394 }
     395 
     396 int32_t IPCThreadState::getLastTransactionBinderFlags() const
     397 {
     398     return mLastTransactionBinderFlags;
     399 }
     400 
     401 void IPCThreadState::restoreCallingIdentity(int64_t token)
     402 {
     403     mCallingUid = (int)(token>>32);
     404     mCallingPid = (int)token;
     405 }
     406 
     407 void IPCThreadState::clearCaller()
     408 {
     409     mCallingPid = getpid();
     410     mCallingUid = getuid();
     411 }
     412 
     413 void IPCThreadState::flushCommands()
     414 {
     415     if (mProcess->mDriverFD <= 0)
     416         return;
     417     talkWithDriver(false);
     418 }
     419 
     420 void IPCThreadState::joinThreadPool(bool isMain)
     421 {
     422     LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL
    ", (void*)pthread_self(), getpid());
     423 
     424     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
     425     
     426     // This thread may have been spawned by a thread that was in the background
     427     // scheduling group, so first we will make sure it is in the default/foreground
     428     // one to avoid performing an initial transaction in the background.
     429     androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
     430         
     431     status_t result;
     432     do {
     433         int32_t cmd;
     434         
     435         // When we've cleared the incoming command queue, process any pending derefs
     436         if (mIn.dataPosition() >= mIn.dataSize()) {
     437             size_t numPending = mPendingWeakDerefs.size();
     438             if (numPending > 0) {
     439                 for (size_t i = 0; i < numPending; i++) {
     440                     RefBase::weakref_type* refs = mPendingWeakDerefs[i];
     441                     refs->decWeak(mProcess.get());
     442                 }
     443                 mPendingWeakDerefs.clear();
     444             }
     445 
     446             numPending = mPendingStrongDerefs.size();
     447             if (numPending > 0) {
     448                 for (size_t i = 0; i < numPending; i++) {
     449                     BBinder* obj = mPendingStrongDerefs[i];
     450                     obj->decStrong(mProcess.get());
     451                 }
     452                 mPendingStrongDerefs.clear();
     453             }
     454         }
     455 
     456         // now get the next command to be processed, waiting if necessary
     457         result = talkWithDriver();
     458         if (result >= NO_ERROR) {
     459             size_t IN = mIn.dataAvail();
     460             if (IN < sizeof(int32_t)) continue;
     461             cmd = mIn.readInt32();
     462             IF_LOG_COMMANDS() {
     463                 alog << "Processing top-level Command: "
     464                     << getReturnString(cmd) << endl;
     465             }
     466 
     467 
     468             result = executeCommand(cmd);
     469         }
     470         
     471         // After executing the command, ensure that the thread is returned to the
     472         // default cgroup before rejoining the pool.  The driver takes care of
     473         // restoring the priority, but doesn't do anything with cgroups so we
     474         // need to take care of that here in userspace.  Note that we do make
     475         // sure to go in the foreground after executing a transaction, but
     476         // there are other callbacks into user code that could have changed
     477         // our group so we want to make absolutely sure it is put back.
     478         androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
     479 
     480         // Let this thread exit the thread pool if it is no longer
     481         // needed and it is not the main process thread.
     482         if(result == TIMED_OUT && !isMain) {
     483             break;
     484         }
     485     } while (result != -ECONNREFUSED && result != -EBADF);
     486 
     487     LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p
    ",
     488         (void*)pthread_self(), getpid(), (void*)result);
     489     
     490     mOut.writeInt32(BC_EXIT_LOOPER);
     491     talkWithDriver(false);
     492 }
     493 
     494 void IPCThreadState::stopProcess(bool immediate)
     495 {
     496     //LOGI("**** STOPPING PROCESS");
     497     flushCommands();
     498     int fd = mProcess->mDriverFD;
     499     mProcess->mDriverFD = -1;
     500     close(fd);
     501     //kill(getpid(), SIGKILL);
     502 }
     503 
     504 status_t IPCThreadState::transact(int32_t handle,
     505                                   uint32_t code, const Parcel& data,
     506                                   Parcel* reply, uint32_t flags)
     507 {
     508     status_t err = data.errorCheck();
     509 
     510     flags |= TF_ACCEPT_FDS;
     511 
     512     IF_LOG_TRANSACTIONS() {
     513         TextOutput::Bundle _b(alog);
     514         alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
     515             << handle << " / code " << TypeCode(code) << ": "
     516             << indent << data << dedent << endl;
     517     }
     518     
     519     if (err == NO_ERROR) {
     520         LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
     521             (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
     522         err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
     523     }
     524     
     525     if (err != NO_ERROR) {
     526         if (reply) reply->setError(err);
     527         return (mLastError = err);
     528     }
     529     
     530     if ((flags & TF_ONE_WAY) == 0) {
     531         #if 0
     532         if (code == 4) { // relayout
     533             LOGI(">>>>>> CALLING transaction 4");
     534         } else {
     535             LOGI(">>>>>> CALLING transaction %d", code);
     536         }
     537         #endif
     538         if (reply) {
     539             err = waitForResponse(reply);
     540         } else {
     541             Parcel fakeReply;
     542             err = waitForResponse(&fakeReply);
     543         }
     544         #if 0
     545         if (code == 4) { // relayout
     546             LOGI("<<<<<< RETURNING transaction 4");
     547         } else {
     548             LOGI("<<<<<< RETURNING transaction %d", code);
     549         }
     550         #endif
     551         
     552         IF_LOG_TRANSACTIONS() {
     553             TextOutput::Bundle _b(alog);
     554             alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
     555                 << handle << ": ";
     556             if (reply) alog << indent << *reply << dedent << endl;
     557             else alog << "(none requested)" << endl;
     558         }
     559     } else {
     560         err = waitForResponse(NULL, NULL);
     561     }
     562     
     563     return err;
     564 }
     565 
     566 void IPCThreadState::incStrongHandle(int32_t handle)
     567 {
     568     LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)
    ", handle);
     569     mOut.writeInt32(BC_ACQUIRE);
     570     mOut.writeInt32(handle);
     571 }
     572 
     573 void IPCThreadState::decStrongHandle(int32_t handle)
     574 {
     575     LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)
    ", handle);
     576     mOut.writeInt32(BC_RELEASE);
     577     mOut.writeInt32(handle);
     578 }
     579 
     580 void IPCThreadState::incWeakHandle(int32_t handle)
     581 {
     582     LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)
    ", handle);
     583     mOut.writeInt32(BC_INCREFS);
     584     mOut.writeInt32(handle);
     585 }
     586 
     587 void IPCThreadState::decWeakHandle(int32_t handle)
     588 {
     589     LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)
    ", handle);
     590     mOut.writeInt32(BC_DECREFS);
     591     mOut.writeInt32(handle);
     592 }
     593 
     594 status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
     595 {
     596     LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)
    ", handle);
     597     mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
     598     mOut.writeInt32(0); // xxx was thread priority
     599     mOut.writeInt32(handle);
     600     status_t result = UNKNOWN_ERROR;
     601     
     602     waitForResponse(NULL, &result);
     603     
     604 #if LOG_REFCOUNTS
     605     printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s
    ",
     606         handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
     607 #endif
     608     
     609     return result;
     610 }
     611 
     612 void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
     613 {
     614 #if LOG_REFCOUNTS
     615     printf("IPCThreadState::expungeHandle(%ld)
    ", handle);
     616 #endif
     617     self()->mProcess->expungeHandle(handle, binder);
     618 }
     619 
     620 status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
     621 {
     622     mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
     623     mOut.writeInt32((int32_t)handle);
     624     mOut.writeInt32((int32_t)proxy);
     625     return NO_ERROR;
     626 }
     627 
     628 status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
     629 {
     630     mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
     631     mOut.writeInt32((int32_t)handle);
     632     mOut.writeInt32((int32_t)proxy);
     633     return NO_ERROR;
     634 }
     635 
     636 IPCThreadState::IPCThreadState()
     637     : mProcess(ProcessState::self()),
     638       mMyThreadId(androidGetTid()),
     639       mStrictModePolicy(0),
     640       mLastTransactionBinderFlags(0)
     641 {
     642     pthread_setspecific(gTLS, this);
     643     clearCaller();
     644     mIn.setDataCapacity(256);
     645     mOut.setDataCapacity(256);
     646 }
     647 
     648 IPCThreadState::~IPCThreadState()
     649 {
     650 }
     651 
     652 status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
     653 {
     654     status_t err;
     655     status_t statusBuffer;
     656     err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
     657     if (err < NO_ERROR) return err;
     658     
     659     return waitForResponse(NULL, NULL);
     660 }
     661 
     662 status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
     663 {
     664     int32_t cmd;
     665     int32_t err;
     666 
     667     while (1) {
     668         if ((err=talkWithDriver()) < NO_ERROR) break;
     669         err = mIn.errorCheck();
     670         if (err < NO_ERROR) break;
     671         if (mIn.dataAvail() == 0) continue;
     672         
     673         cmd = mIn.readInt32();
     674         
     675         IF_LOG_COMMANDS() {
     676             alog << "Processing waitForResponse Command: "
     677                 << getReturnString(cmd) << endl;
     678         }
     679 
     680         switch (cmd) {
     681         case BR_TRANSACTION_COMPLETE:
     682             if (!reply && !acquireResult) goto finish;
     683             break;
     684         
     685         case BR_DEAD_REPLY:
     686             err = DEAD_OBJECT;
     687             goto finish;
     688 
     689         case BR_FAILED_REPLY:
     690             err = FAILED_TRANSACTION;
     691             goto finish;
     692         
     693         case BR_ACQUIRE_RESULT:
     694             {
     695                 LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
     696                 const int32_t result = mIn.readInt32();
     697                 if (!acquireResult) continue;
     698                 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
     699             }
     700             goto finish;
     701         
     702         case BR_REPLY:
     703             {
     704                 binder_transaction_data tr;
     705                 err = mIn.read(&tr, sizeof(tr));
     706                 LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
     707                 if (err != NO_ERROR) goto finish;
     708 
     709                 if (reply) {
     710                     if ((tr.flags & TF_STATUS_CODE) == 0) {
     711                         reply->ipcSetDataReference(
     712                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
     713                             tr.data_size,
     714                             reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
     715                             tr.offsets_size/sizeof(size_t),
     716                             freeBuffer, this);
     717                     } else {
     718                         err = *static_cast<const status_t*>(tr.data.ptr.buffer);
     719                         freeBuffer(NULL,
     720                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
     721                             tr.data_size,
     722                             reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
     723                             tr.offsets_size/sizeof(size_t), this);
     724                     }
     725                 } else {
     726                     freeBuffer(NULL,
     727                         reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
     728                         tr.data_size,
     729                         reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
     730                         tr.offsets_size/sizeof(size_t), this);
     731                     continue;
     732                 }
     733             }
     734             goto finish;
     735 
     736         default:
     737             err = executeCommand(cmd);
     738             if (err != NO_ERROR) goto finish;
     739             break;
     740         }
     741     }
     742 
     743 finish:
     744     if (err != NO_ERROR) {
     745         if (acquireResult) *acquireResult = err;
     746         if (reply) reply->setError(err);
     747         mLastError = err;
     748     }
     749     
     750     return err;
     751 }
     752 
     753 status_t IPCThreadState::talkWithDriver(bool doReceive)
     754 {
     755     LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
     756     
     757     binder_write_read bwr;
     758     
     759     // Is the read buffer empty?
     760     const bool needRead = mIn.dataPosition() >= mIn.dataSize();
     761     
     762     // We don't want to write anything if we are still reading
     763     // from data left in the input buffer and the caller
     764     // has requested to read the next data.
     765     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
     766     
     767     bwr.write_size = outAvail;
     768     bwr.write_buffer = (long unsigned int)mOut.data();
     769 
     770     // This is what we'll read.
     771     if (doReceive && needRead) {
     772         bwr.read_size = mIn.dataCapacity();
     773         bwr.read_buffer = (long unsigned int)mIn.data();
     774     } else {
     775         bwr.read_size = 0;
     776     }
     777 
     778     IF_LOG_COMMANDS() {
     779         TextOutput::Bundle _b(alog);
     780         if (outAvail != 0) {
     781             alog << "Sending commands to driver: " << indent;
     782             const void* cmds = (const void*)bwr.write_buffer;
     783             const void* end = ((const uint8_t*)cmds)+bwr.write_size;
     784             alog << HexDump(cmds, bwr.write_size) << endl;
     785             while (cmds < end) cmds = printCommand(alog, cmds);
     786             alog << dedent;
     787         }
     788         alog << "Size of receive buffer: " << bwr.read_size
     789             << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
     790     }
     791     
     792     // Return immediately if there is nothing to do.
     793     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
     794 
     795     bwr.write_consumed = 0;
     796     bwr.read_consumed = 0;
     797     status_t err;
     798     do {
     799         IF_LOG_COMMANDS() {
     800             alog << "About to read/write, write size = " << mOut.dataSize() << endl;
     801         }
     802 #if defined(HAVE_ANDROID_OS)
     803         if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
     804             err = NO_ERROR;
     805         else
     806             err = -errno;
     807 #else
     808         err = INVALID_OPERATION;
     809 #endif
     810         IF_LOG_COMMANDS() {
     811             alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
     812         }
     813     } while (err == -EINTR);
     814 
     815     IF_LOG_COMMANDS() {
     816         alog << "Our err: " << (void*)err << ", write consumed: "
     817             << bwr.write_consumed << " (of " << mOut.dataSize()
     818             << "), read consumed: " << bwr.read_consumed << endl;
     819     }
     820 
     821     if (err >= NO_ERROR) {
     822         if (bwr.write_consumed > 0) {
     823             if (bwr.write_consumed < (ssize_t)mOut.dataSize())
     824                 mOut.remove(0, bwr.write_consumed);
     825             else
     826                 mOut.setDataSize(0);
     827         }
     828         if (bwr.read_consumed > 0) {
     829             mIn.setDataSize(bwr.read_consumed);
     830             mIn.setDataPosition(0);
     831         }
     832         IF_LOG_COMMANDS() {
     833             TextOutput::Bundle _b(alog);
     834             alog << "Remaining data size: " << mOut.dataSize() << endl;
     835             alog << "Received commands from driver: " << indent;
     836             const void* cmds = mIn.data();
     837             const void* end = mIn.data() + mIn.dataSize();
     838             alog << HexDump(cmds, mIn.dataSize()) << endl;
     839             while (cmds < end) cmds = printReturnCommand(alog, cmds);
     840             alog << dedent;
     841         }
     842         return NO_ERROR;
     843     }
     844     
     845     return err;
     846 }
     847 
     848 status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
     849     int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
     850 {
     851     binder_transaction_data tr;
     852 
     853     tr.target.handle = handle;
     854     tr.code = code;
     855     tr.flags = binderFlags;
     856     tr.cookie = 0;
     857     tr.sender_pid = 0;
     858     tr.sender_euid = 0;
     859     
     860     const status_t err = data.errorCheck();
     861     if (err == NO_ERROR) {
     862         tr.data_size = data.ipcDataSize();
     863         tr.data.ptr.buffer = data.ipcData();
     864         tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
     865         tr.data.ptr.offsets = data.ipcObjects();
     866     } else if (statusBuffer) {
     867         tr.flags |= TF_STATUS_CODE;
     868         *statusBuffer = err;
     869         tr.data_size = sizeof(status_t);
     870         tr.data.ptr.buffer = statusBuffer;
     871         tr.offsets_size = 0;
     872         tr.data.ptr.offsets = NULL;
     873     } else {
     874         return (mLastError = err);
     875     }
     876     
     877     mOut.writeInt32(cmd);
     878     mOut.write(&tr, sizeof(tr));
     879     
     880     return NO_ERROR;
     881 }
     882 
     883 sp<BBinder> the_context_object;
     884 
     885 void setTheContextObject(sp<BBinder> obj)
     886 {
     887     the_context_object = obj;
     888 }
     889 
     890 status_t IPCThreadState::executeCommand(int32_t cmd)
     891 {
     892     BBinder* obj;
     893     RefBase::weakref_type* refs;
     894     status_t result = NO_ERROR;
     895     
     896     switch (cmd) {
     897     case BR_ERROR:
     898         result = mIn.readInt32();
     899         break;
     900         
     901     case BR_OK:
     902         break;
     903         
     904     case BR_ACQUIRE:
     905         refs = (RefBase::weakref_type*)mIn.readInt32();
     906         obj = (BBinder*)mIn.readInt32();
     907         LOG_ASSERT(refs->refBase() == obj,
     908                    "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
     909                    refs, obj, refs->refBase());
     910         obj->incStrong(mProcess.get());
     911         IF_LOG_REMOTEREFS() {
     912             LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
     913             obj->printRefs();
     914         }
     915         mOut.writeInt32(BC_ACQUIRE_DONE);
     916         mOut.writeInt32((int32_t)refs);
     917         mOut.writeInt32((int32_t)obj);
     918         break;
     919         
     920     case BR_RELEASE:
     921         refs = (RefBase::weakref_type*)mIn.readInt32();
     922         obj = (BBinder*)mIn.readInt32();
     923         LOG_ASSERT(refs->refBase() == obj,
     924                    "BR_RELEASE: object %p does not match cookie %p (expected %p)",
     925                    refs, obj, refs->refBase());
     926         IF_LOG_REMOTEREFS() {
     927             LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
     928             obj->printRefs();
     929         }
     930         mPendingStrongDerefs.push(obj);
     931         break;
     932         
     933     case BR_INCREFS:
     934         refs = (RefBase::weakref_type*)mIn.readInt32();
     935         obj = (BBinder*)mIn.readInt32();
     936         refs->incWeak(mProcess.get());
     937         mOut.writeInt32(BC_INCREFS_DONE);
     938         mOut.writeInt32((int32_t)refs);
     939         mOut.writeInt32((int32_t)obj);
     940         break;
     941         
     942     case BR_DECREFS:
     943         refs = (RefBase::weakref_type*)mIn.readInt32();
     944         obj = (BBinder*)mIn.readInt32();
     945         // NOTE: This assertion is not valid, because the object may no
     946         // longer exist (thus the (BBinder*)cast above resulting in a different
     947         // memory address).
     948         //LOG_ASSERT(refs->refBase() == obj,
     949         //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
     950         //           refs, obj, refs->refBase());
     951         mPendingWeakDerefs.push(refs);
     952         break;
     953         
     954     case BR_ATTEMPT_ACQUIRE:
     955         refs = (RefBase::weakref_type*)mIn.readInt32();
     956         obj = (BBinder*)mIn.readInt32();
     957          
     958         {
     959             const bool success = refs->attemptIncStrong(mProcess.get());
     960             LOG_ASSERT(success && refs->refBase() == obj,
     961                        "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
     962                        refs, obj, refs->refBase());
     963             
     964             mOut.writeInt32(BC_ACQUIRE_RESULT);
     965             mOut.writeInt32((int32_t)success);
     966         }
     967         break;
     968     
     969     case BR_TRANSACTION:
     970         {
     971             binder_transaction_data tr;
     972             result = mIn.read(&tr, sizeof(tr));
     973             LOG_ASSERT(result == NO_ERROR,
     974                 "Not enough command data for brTRANSACTION");
     975             if (result != NO_ERROR) break;
     976             
     977             Parcel buffer;
     978             buffer.ipcSetDataReference(
     979                 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
     980                 tr.data_size,
     981                 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
     982                 tr.offsets_size/sizeof(size_t), freeBuffer, this);
     983             
     984             const pid_t origPid = mCallingPid;
     985             const uid_t origUid = mCallingUid;
     986             
     987             mCallingPid = tr.sender_pid;
     988             mCallingUid = tr.sender_euid;
     989             
     990             int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
     991             if (gDisableBackgroundScheduling) {
     992                 if (curPrio > ANDROID_PRIORITY_NORMAL) {
     993                     // We have inherited a reduced priority from the caller, but do not
     994                     // want to run in that state in this process.  The driver set our
     995                     // priority already (though not our scheduling class), so bounce
     996                     // it back to the default before invoking the transaction.
     997                     setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
     998                 }
     999             } else {
    1000                 if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
    1001                     // We want to use the inherited priority from the caller.
    1002                     // Ensure this thread is in the background scheduling class,
    1003                     // since the driver won't modify scheduling classes for us.
    1004                     // The scheduling group is reset to default by the caller
    1005                     // once this method returns after the transaction is complete.
    1006                     androidSetThreadSchedulingGroup(mMyThreadId,
    1007                                                     ANDROID_TGROUP_BG_NONINTERACT);
    1008                 }
    1009             }
    1010 
    1011             //LOGI(">>>> TRANSACT from pid %d uid %d
    ", mCallingPid, mCallingUid);
    1012             
    1013             Parcel reply;
    1014             IF_LOG_TRANSACTIONS() {
    1015                 TextOutput::Bundle _b(alog);
    1016                 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
    1017                     << " / obj " << tr.target.ptr << " / code "
    1018                     << TypeCode(tr.code) << ": " << indent << buffer
    1019                     << dedent << endl
    1020                     << "Data addr = "
    1021                     << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
    1022                     << ", offsets addr="
    1023                     << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
    1024             }
    1025             if (tr.target.ptr) {
    1026                 sp<BBinder> b((BBinder*)tr.cookie);
    1027                 const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
    1028                 if (error < NO_ERROR) reply.setError(error);
    1029 
    1030             } else {
    1031                 const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
    1032                 if (error < NO_ERROR) reply.setError(error);
    1033             }
    1034             
    1035             //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d
    ",
    1036             //     mCallingPid, origPid, origUid);
    1037             
    1038             if ((tr.flags & TF_ONE_WAY) == 0) {
    1039                 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
    1040                 sendReply(reply, 0);
    1041             } else {
    1042                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
    1043             }
    1044             
    1045             mCallingPid = origPid;
    1046             mCallingUid = origUid;
    1047 
    1048             IF_LOG_TRANSACTIONS() {
    1049                 TextOutput::Bundle _b(alog);
    1050                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
    1051                     << tr.target.ptr << ": " << indent << reply << dedent << endl;
    1052             }
    1053             
    1054         }
    1055         break;
    1056     
    1057     case BR_DEAD_BINDER:
    1058         {
    1059             BpBinder *proxy = (BpBinder*)mIn.readInt32();
    1060             proxy->sendObituary();
    1061             mOut.writeInt32(BC_DEAD_BINDER_DONE);
    1062             mOut.writeInt32((int32_t)proxy);
    1063         } break;
    1064         
    1065     case BR_CLEAR_DEATH_NOTIFICATION_DONE:
    1066         {
    1067             BpBinder *proxy = (BpBinder*)mIn.readInt32();
    1068             proxy->getWeakRefs()->decWeak(proxy);
    1069         } break;
    1070         
    1071     case BR_FINISHED:
    1072         result = TIMED_OUT;
    1073         break;
    1074         
    1075     case BR_NOOP:
    1076         break;
    1077         
    1078     case BR_SPAWN_LOOPER:
    1079         mProcess->spawnPooledThread(false);
    1080         break;
    1081         
    1082     default:
    1083         printf("*** BAD COMMAND %d received from Binder driver
    ", cmd);
    1084         result = UNKNOWN_ERROR;
    1085         break;
    1086     }
    1087 
    1088     if (result != NO_ERROR) {
    1089         mLastError = result;
    1090     }
    1091     
    1092     return result;
    1093 }
    1094 
    1095 void IPCThreadState::threadDestructor(void *st)
    1096 {
    1097     IPCThreadState* const self = static_cast<IPCThreadState*>(st);
    1098     if (self) {
    1099         self->flushCommands();
    1100 #if defined(HAVE_ANDROID_OS)
    1101         ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
    1102 #endif
    1103         delete self;
    1104     }
    1105 }
    1106 
    1107 
    1108 void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
    1109                                 const size_t* objects, size_t objectsSize,
    1110                                 void* cookie)
    1111 {
    1112     //LOGI("Freeing parcel %p", &parcel);
    1113     IF_LOG_COMMANDS() {
    1114         alog << "Writing BC_FREE_BUFFER for " << data << endl;
    1115     }
    1116     LOG_ASSERT(data != NULL, "Called with NULL data");
    1117     if (parcel != NULL) parcel->closeFileDescriptors();
    1118     IPCThreadState* state = self();
    1119     state->mOut.writeInt32(BC_FREE_BUFFER);
    1120     state->mOut.writeInt32((int32_t)data);
    1121 }
    1122 
    1123 }; // namespace android
    IPCThreadState
  • What is IServiceManager?
  •  1 namespace android {
     2 IInterface::IInterface(): RefBase() {}
     3 IInterface::~IInterface() {
     4 }
     5 sp<IBinder> IInterface::asBinder()
     6 {
     7     return this ? onAsBinder() : NULL;
     8 }
     9 sp<const IBinder> IInterface::asBinder() const
    10 {
    11     return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
    12 }
    13 };
    IInterface
  •  1 namespace android {
     2 class IServiceManager : public IInterface
     3 {
     4 public:
     5     DECLARE_META_INTERFACE(ServiceManager);
     6     virtual sp<IBinder> getService( const String16& name) const = 0;
     7     virtual sp<IBinder> checkService( const String16& name) const = 0;
     8     virtual status_t   addService( const String16& name,const sp<IBinder>& service) = 0;
     9     virtual Vector<String16> listServices() = 0;
    10     enum {
    11         GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
    12         CHECK_SERVICE_TRANSACTION,
    13         ADD_SERVICE_TRANSACTION,
    14         LIST_SERVICES_TRANSACTION,
    15     };
    16 };
    17 sp<IServiceManager> defaultServiceManager();
    18 template<typename INTERFACE>
    19 status_t getService(const String16& name, sp<INTERFACE>* outService)
    20 {
    21     const sp<IServiceManager> sm = defaultServiceManager();
    22     if (sm != NULL) {
    23         *outService = interface_cast<INTERFACE>(sm->getService(name));
    24         if ((*outService) != NULL) return NO_ERROR;
    25     }
    26     return NAME_NOT_FOUND;
    27 }
    28 bool checkCallingPermission(const String16& permission);
    29 bool checkCallingPermission(const String16& permission,int32_t* outPid, int32_t* outUid);
    30 bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
    31 class BnServiceManager : public BnInterface<IServiceManager>
    32 {
    33 public:
    34     virtual status_t   onTransact( uint32_t code,
    35                                     const Parcel& data,
    36                                     Parcel* reply,
    37                                     uint32_t flags = 0);
    38 };
    39 }; 
    IServiceManager.h
      1 /**
      2  * Copyright (C) 2005 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_TAG "ServiceManager"
     18 
     19 #include <binder/IServiceManager.h>
     20 
     21 #include <utils/Debug.h>
     22 #include <utils/Log.h>
     23 #include <binder/IPCThreadState.h>
     24 #include <binder/Parcel.h>
     25 #include <utils/String8.h>
     26 #include <utils/SystemClock.h>
     27 
     28 #include <private/binder/Static.h>
     29 
     30 #include <unistd.h>
     31 
     32 namespace android {
     33 
     34 sp<IServiceManager> defaultServiceManager()
     35 {
     36     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
     37     
     38     {
     39         AutoMutex _l(gDefaultServiceManagerLock);
     40         if (gDefaultServiceManager == NULL) {
     41             gDefaultServiceManager = interface_cast<IServiceManager>(
     42                 ProcessState::self()->getContextObject(NULL));
     43         }
     44     }
     45     
     46     return gDefaultServiceManager;
     47 }
     48 
     49 bool checkCallingPermission(const String16& permission)
     50 {
     51     return checkCallingPermission(permission, NULL, NULL);
     52 }
     53 
     54 static String16 _permission("permission");
     55 
     56 
     57 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
     58 {
     59     IPCThreadState* ipcState = IPCThreadState::self();
     60     pid_t pid = ipcState->getCallingPid();
     61     uid_t uid = ipcState->getCallingUid();
     62     if (outPid) *outPid = pid;
     63     if (outUid) *outUid = uid;
     64     return checkPermission(permission, pid, uid);
     65 }
     66 
     67 bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
     68 {
     69     sp<IPermissionController> pc;
     70     gDefaultServiceManagerLock.lock();
     71     pc = gPermissionController;
     72     gDefaultServiceManagerLock.unlock();
     73     
     74     int64_t startTime = 0;
     75 
     76     while (true) {
     77         if (pc != NULL) {
     78             bool res = pc->checkPermission(permission, pid, uid);
     79             if (res) {
     80                 if (startTime != 0) {
     81                     LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
     82                             (int)((uptimeMillis()-startTime)/1000),
     83                             String8(permission).string(), uid, pid);
     84                 }
     85                 return res;
     86             }
     87             
     88             // Is this a permission failure, or did the controller go away?
     89             if (pc->asBinder()->isBinderAlive()) {
     90                 LOGW("Permission failure: %s from uid=%d pid=%d",
     91                         String8(permission).string(), uid, pid);
     92                 return false;
     93             }
     94             
     95             // Object is dead!
     96             gDefaultServiceManagerLock.lock();
     97             if (gPermissionController == pc) {
     98                 gPermissionController = NULL;
     99             }
    100             gDefaultServiceManagerLock.unlock();
    101         }
    102     
    103         // Need to retrieve the permission controller.
    104         sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
    105         if (binder == NULL) {
    106             // Wait for the permission controller to come back...
    107             if (startTime == 0) {
    108                 startTime = uptimeMillis();
    109                 LOGI("Waiting to check permission %s from uid=%d pid=%d",
    110                         String8(permission).string(), uid, pid);
    111             }
    112             sleep(1);
    113         } else {
    114             pc = interface_cast<IPermissionController>(binder);
    115             // Install the new permission controller, and try again.        
    116             gDefaultServiceManagerLock.lock();
    117             gPermissionController = pc;
    118             gDefaultServiceManagerLock.unlock();
    119         }
    120     }
    121 }
    122 
    123 // ----------------------------------------------------------------------
    124 
    125 class BpServiceManager : public BpInterface<IServiceManager>
    126 {
    127 public:
    128     BpServiceManager(const sp<IBinder>& impl)
    129         : BpInterface<IServiceManager>(impl)
    130     {
    131     }
    132 
    133     virtual sp<IBinder> getService(const String16& name) const
    134     {
    135         unsigned n;
    136         for (n = 0; n < 5; n++){
    137             sp<IBinder> svc = checkService(name);
    138             if (svc != NULL) return svc;
    139             LOGI("Waiting for service %s...
    ", String8(name).string());
    140             sleep(1);
    141         }
    142         return NULL;
    143     }
    144 
    145     virtual sp<IBinder> checkService( const String16& name) const
    146     {
    147         Parcel data, reply;
    148         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    149         data.writeString16(name);
    150         remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    151         return reply.readStrongBinder();
    152     }
    153 
    154     virtual status_t addService(const String16& name, const sp<IBinder>& service)
    155     {
    156         Parcel data, reply;
    157         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    158         data.writeString16(name);
    159         data.writeStrongBinder(service);
    160         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    161         return err == NO_ERROR ? reply.readExceptionCode() : err;
    162     }
    163 
    164     virtual Vector<String16> listServices()
    165     {
    166         Vector<String16> res;
    167         int n = 0;
    168 
    169         for (;;) {
    170             Parcel data, reply;
    171             data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    172             data.writeInt32(n++);
    173             status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
    174             if (err != NO_ERROR)
    175                 break;
    176             res.add(reply.readString16());
    177         }
    178         return res;
    179     }
    180 };
    181 
    182 IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
    183 
    184 // ----------------------------------------------------------------------
    185 
    186 status_t BnServiceManager::onTransact(
    187     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    188 {
    189     //printf("ServiceManager received: "); data.print();
    190     switch(code) {
    191         case GET_SERVICE_TRANSACTION: {
    192             CHECK_INTERFACE(IServiceManager, data, reply);
    193             String16 which = data.readString16();
    194             sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
    195             reply->writeStrongBinder(b);
    196             return NO_ERROR;
    197         } break;
    198         case CHECK_SERVICE_TRANSACTION: {
    199             CHECK_INTERFACE(IServiceManager, data, reply);
    200             String16 which = data.readString16();
    201             sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
    202             reply->writeStrongBinder(b);
    203             return NO_ERROR;
    204         } break;
    205         case ADD_SERVICE_TRANSACTION: {
    206             CHECK_INTERFACE(IServiceManager, data, reply);
    207             String16 which = data.readString16();
    208             sp<IBinder> b = data.readStrongBinder();
    209             status_t err = addService(which, b);
    210             reply->writeInt32(err);
    211             return NO_ERROR;
    212         } break;
    213         case LIST_SERVICES_TRANSACTION: {
    214             CHECK_INTERFACE(IServiceManager, data, reply);
    215             Vector<String16> list = listServices();
    216             const size_t N = list.size();
    217             reply->writeInt32(N);
    218             for (size_t i=0; i<N; i++) {
    219                 reply->writeString16(list[i]);
    220             }
    221             return NO_ERROR;
    222         } break;
    223         default:
    224             return BBinder::onTransact(code, data, reply, flags);
    225     }
    226 }
    227 
    228 }; // namespace android
    IServiceManager.cpp
  • What is defaultServiceManager?
  •  1 sp<IServiceManager> defaultServiceManager() //global function
     2 {
     3     if (gDefaultServiceManager != NULL) 
     4         return gDefaultServiceManager;    
     5     {
     6         AutoMutex _l(gDefaultServiceManagerLock);
     7         if (gDefaultServiceManager == NULL) {
     8             gDefaultServiceManager = interface_cast<IServiceManager>(
     9                 ProcessState::self()->getContextObject(NULL));
    10         }
    11     }    
    12     return gDefaultServiceManager;
    13 }
    1 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
    2 {
    3     return getStrongProxyForHandle(0);
    4 }
     1 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
     2 {
     3     sp<IBinder> result;
     4     AutoMutex _l(mLock);
     5     handle_entry* e = lookupHandleLocked(handle)
     6     if (e != NULL) {
     7         IBinder* b = e->binder;
     8         if (b == NULL || !e->refs->attemptIncWeak(this)) {
     9             b = new BpBinder(handle); 
    10             e->binder = b;
    11             if (b) e->refs = b->getWeakRefs();
    12             result = b;
    13         } else {
    14             result.force_set(b);
    15             e->refs->decWeak(this);
    16         }
    17     }
    18     return result;
    19 }

AudioFlinger

MediaPlayerService

  • Create service in current process and add it to service manager
  •  1 void MediaPlayerService::instantiate() {
     2     defaultServiceManager()->addService(
     3             String16("media.player"), new MediaPlayerService());
     4 }
     5 //
     6 MediaPlayerService::MediaPlayerService()
     7 {
     8     LOGV("MediaPlayerService created");
     9     mNextConnId = 1;
    10 
    11     mBatteryAudio.refCount = 0;
    12     for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
    13         mBatteryAudio.deviceOn[i] = 0;
    14         mBatteryAudio.lastTime[i] = 0;
    15         mBatteryAudio.totalTime[i] = 0;
    16     }
    17     // speaker is on by default
    18     mBatteryAudio.deviceOn[SPEAKER] = 1;
    19 } 
  • Now we have MediaService information in service manager
  • MediaPlayerService is subclass of BnMediaPlayerService
  • 1 class MediaPlayerService : public BnMediaPlayerService
  • Where is BnMediaPlayerService
  •  1 namespace android {
     2 class IMediaRecorder;
     3 class IOMX;
     4 struct IStreamSource;
     5 class IMediaPlayerService: public IInterface
     6 {
     7 public:
     8     DECLARE_META_INTERFACE(MediaPlayerService);
     9     virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
    10     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
    11     virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0;
    12 
    13     virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
    14     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
    15     virtual sp<IOMX>            getOMX() = 0;
    16     ............
    17     virtual void addBatteryData(uint32_t params) = 0;
    18     virtual status_t pullBatteryData(Parcel* reply) = 0;
    19 };
    20 class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
    21 {
    22 public:
    23     virtual status_t    onTransact( uint32_t code,
    24                                     const Parcel& data,
    25                                     Parcel* reply,
    26                                     uint32_t flags = 0);
    27 };
    28 };
  • What does BnMediaPlayerService do?
  • How to use MediaPlayer
  • 1 MediaPlayer mp = new MediaPlayer();//new a MediaPlayer object
    2 mp.setDataSource("/sdcard/test.mp3");//set music path
    3 mp.prepare();//prepare
    4 mp.start();//start to play
  • JNI of MediaPlayer

  •   1 /**
      2 **
      3 ** Copyright 2007, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 //#define LOG_NDEBUG 0
     19 #define LOG_TAG "MediaPlayer-JNI"
     20 #include "utils/Log.h"
     21 
     22 #include <media/mediaplayer.h>
     23 #include <media/MediaPlayerInterface.h>
     24 #include <stdio.h>
     25 #include <assert.h>
     26 #include <limits.h>
     27 #include <unistd.h>
     28 #include <fcntl.h>
     29 #include <utils/threads.h>
     30 #include "jni.h"
     31 #include "JNIHelp.h"
     32 #include "android_runtime/AndroidRuntime.h"
     33 #include "android_runtime/android_view_Surface.h"
     34 #include "utils/Errors.h"  // for status_t
     35 #include "utils/KeyedVector.h"
     36 #include "utils/String8.h"
     37 #include "android_media_Utils.h"
     38 
     39 #include "android_util_Binder.h"
     40 #include <binder/Parcel.h>
     41 #include <gui/ISurfaceTexture.h>
     42 #include <surfaceflinger/Surface.h>
     43 #include <binder/IPCThreadState.h>
     44 #include <binder/IServiceManager.h>
     45 
     46 // ----------------------------------------------------------------------------
     47 
     48 using namespace android;
     49 
     50 // ----------------------------------------------------------------------------
     51 
     52 struct fields_t {
     53     jfieldID    context;
     54     jfieldID    surface_texture;
     55 
     56     jmethodID   post_event;
     57 };
     58 static fields_t fields;
     59 
     60 static Mutex sLock;
     61 
     62 // ----------------------------------------------------------------------------
     63 // ref-counted object for callbacks
     64 class JNIMediaPlayerListener: public MediaPlayerListener
     65 {
     66 public:
     67     JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
     68     ~JNIMediaPlayerListener();
     69     virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
     70 private:
     71     JNIMediaPlayerListener();
     72     jclass      mClass;     // Reference to MediaPlayer class
     73     jobject     mObject;    // Weak ref to MediaPlayer Java object to call on
     74 };
     75 
     76 JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
     77 {
     78 
     79     // Hold onto the MediaPlayer class for use in calling the static method
     80     // that posts events to the application thread.
     81     jclass clazz = env->GetObjectClass(thiz);
     82     if (clazz == NULL) {
     83         LOGE("Can't find android/media/MediaPlayer");
     84         jniThrowException(env, "java/lang/Exception", NULL);
     85         return;
     86     }
     87     mClass = (jclass)env->NewGlobalRef(clazz);
     88 
     89     // We use a weak reference so the MediaPlayer object can be garbage collected.
     90     // The reference is only used as a proxy for callbacks.
     91     mObject  = env->NewGlobalRef(weak_thiz);
     92 }
     93 
     94 JNIMediaPlayerListener::~JNIMediaPlayerListener()
     95 {
     96     // remove global references
     97     JNIEnv *env = AndroidRuntime::getJNIEnv();
     98     env->DeleteGlobalRef(mObject);
     99     env->DeleteGlobalRef(mClass);
    100 }
    101 
    102 void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj)
    103 {
    104     JNIEnv *env = AndroidRuntime::getJNIEnv();
    105     if (obj && obj->dataSize() > 0) {
    106         jbyteArray jArray = env->NewByteArray(obj->dataSize());
    107         if (jArray != NULL) {
    108             jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
    109             memcpy(nArray, obj->data(), obj->dataSize());
    110             env->ReleaseByteArrayElements(jArray, nArray, 0);
    111             env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
    112                     msg, ext1, ext2, jArray);
    113             env->DeleteLocalRef(jArray);
    114         }
    115     } else {
    116         env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
    117                 msg, ext1, ext2, NULL);
    118     }
    119 }
    120 
    121 // ----------------------------------------------------------------------------
    122 
    123 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
    124 {
    125     Mutex::Autolock l(sLock);
    126     MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);
    127     return sp<MediaPlayer>(p);
    128 }
    129 
    130 static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
    131 {
    132     Mutex::Autolock l(sLock);
    133     sp<MediaPlayer> old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
    134     if (player.get()) {
    135         player->incStrong(thiz);
    136     }
    137     if (old != 0) {
    138         old->decStrong(thiz);
    139     }
    140     env->SetIntField(thiz, fields.context, (int)player.get());
    141     return old;
    142 }
    143 
    144 // If exception is NULL and opStatus is not OK, this method sends an error
    145 // event to the client application; otherwise, if exception is not NULL and
    146 // opStatus is not OK, this method throws the given exception to the client
    147 // application.
    148 static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
    149 {
    150     if (exception == NULL) {  // Don't throw exception. Instead, send an event.
    151         if (opStatus != (status_t) OK) {
    152             sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    153             if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
    154         }
    155     } else {  // Throw exception!
    156         if ( opStatus == (status_t) INVALID_OPERATION ) {
    157             jniThrowException(env, "java/lang/IllegalStateException", NULL);
    158         } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
    159             jniThrowException(env, "java/lang/SecurityException", NULL);
    160         } else if ( opStatus != (status_t) OK ) {
    161             if (strlen(message) > 230) {
    162                // if the message is too long, don't bother displaying the status code
    163                jniThrowException( env, exception, message);
    164             } else {
    165                char msg[256];
    166                 // append the status code to the message
    167                sprintf(msg, "%s: status=0x%X", message, opStatus);
    168                jniThrowException( env, exception, msg);
    169             }
    170         }
    171     }
    172 }
    173 
    174 static void
    175 android_media_MediaPlayer_setDataSourceAndHeaders(
    176         JNIEnv *env, jobject thiz, jstring path,
    177         jobjectArray keys, jobjectArray values) {
    178 
    179     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    180     if (mp == NULL ) {
    181         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    182         return;
    183     }
    184 
    185     if (path == NULL) {
    186         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    187         return;
    188     }
    189 
    190     const char *tmp = env->GetStringUTFChars(path, NULL);
    191     if (tmp == NULL) {  // Out of memory
    192         return;
    193     }
    194     LOGV("setDataSource: path %s", tmp);
    195 
    196     String8 pathStr(tmp);
    197     env->ReleaseStringUTFChars(path, tmp);
    198     tmp = NULL;
    199 
    200     // We build a KeyedVector out of the key and val arrays
    201     KeyedVector<String8, String8> headersVector;
    202     if (!ConvertKeyValueArraysToKeyedVector(
    203             env, keys, values, &headersVector)) {
    204         return;
    205     }
    206 
    207     status_t opStatus =
    208         mp->setDataSource(
    209                 pathStr,
    210                 headersVector.size() > 0? &headersVector : NULL);
    211 
    212     process_media_player_call(
    213             env, thiz, opStatus, "java/io/IOException",
    214             "setDataSource failed." );
    215 }
    216 
    217 static void
    218 android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)
    219 {
    220     android_media_MediaPlayer_setDataSourceAndHeaders(env, thiz, path, NULL, NULL);
    221 }
    222 
    223 static void
    224 android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
    225 {
    226     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    227     if (mp == NULL ) {
    228         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    229         return;
    230     }
    231 
    232     if (fileDescriptor == NULL) {
    233         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    234         return;
    235     }
    236     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    237     LOGV("setDataSourceFD: fd %d", fd);
    238     process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
    239 }
    240 
    241 static sp<ISurfaceTexture>
    242 getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
    243     ISurfaceTexture * const p = (ISurfaceTexture*)env->GetIntField(thiz, fields.surface_texture);
    244     return sp<ISurfaceTexture>(p);
    245 }
    246 
    247 static void
    248 decVideoSurfaceRef(JNIEnv *env, jobject thiz)
    249 {
    250     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    251     if (mp == NULL) {
    252         return;
    253     }
    254 
    255     sp<ISurfaceTexture> old_st = getVideoSurfaceTexture(env, thiz);
    256     if (old_st != NULL) {
    257         old_st->decStrong(thiz);
    258     }
    259 }
    260 
    261 static void
    262 setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
    263 {
    264     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    265     if (mp == NULL) {
    266         if (mediaPlayerMustBeAlive) {
    267             jniThrowException(env, "java/lang/IllegalStateException", NULL);
    268         }
    269         return;
    270     }
    271 
    272     decVideoSurfaceRef(env, thiz);
    273 
    274     sp<ISurfaceTexture> new_st;
    275     if (jsurface) {
    276         sp<Surface> surface(Surface_getSurface(env, jsurface));
    277         if (surface != NULL) {
    278             new_st = surface->getSurfaceTexture();
    279             new_st->incStrong(thiz);
    280         } else {
    281             jniThrowException(env, "java/lang/IllegalArgumentException",
    282                     "The surface has been released");
    283             return;
    284         }
    285     }
    286 
    287     env->SetIntField(thiz, fields.surface_texture, (int)new_st.get());
    288 
    289     // This will fail if the media player has not been initialized yet. This
    290     // can be the case if setDisplay() on MediaPlayer.java has been called
    291     // before setDataSource(). The redundant call to setVideoSurfaceTexture()
    292     // in prepare/prepareAsync covers for this case.
    293     mp->setVideoSurfaceTexture(new_st);
    294 }
    295 
    296 static void
    297 android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
    298 {
    299     setVideoSurface(env, thiz, jsurface, true /** mediaPlayerMustBeAlive */);
    300 }
    301 
    302 static void
    303 android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
    304 {
    305     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    306     if (mp == NULL ) {
    307         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    308         return;
    309     }
    310 
    311     // Handle the case where the display surface was set before the mp was
    312     // initialized. We try again to make it stick.
    313     sp<ISurfaceTexture> st = getVideoSurfaceTexture(env, thiz);
    314     mp->setVideoSurfaceTexture(st);
    315 
    316     process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
    317 }
    318 
    319 static void
    320 android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
    321 {
    322     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    323     if (mp == NULL ) {
    324         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    325         return;
    326     }
    327 
    328     // Handle the case where the display surface was set before the mp was
    329     // initialized. We try again to make it stick.
    330     sp<ISurfaceTexture> st = getVideoSurfaceTexture(env, thiz);
    331     mp->setVideoSurfaceTexture(st);
    332 
    333     process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
    334 }
    335 
    336 static void
    337 android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
    338 {
    339     LOGV("start");
    340     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    341     if (mp == NULL ) {
    342         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    343         return;
    344     }
    345     process_media_player_call( env, thiz, mp->start(), NULL, NULL );
    346 }
    347 
    348 static void
    349 android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
    350 {
    351     LOGV("stop");
    352     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    353     if (mp == NULL ) {
    354         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    355         return;
    356     }
    357     process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
    358 }
    359 
    360 static void
    361 android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
    362 {
    363     LOGV("pause");
    364     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    365     if (mp == NULL ) {
    366         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    367         return;
    368     }
    369     process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
    370 }
    371 
    372 static jboolean
    373 android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
    374 {
    375     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    376     if (mp == NULL ) {
    377         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    378         return false;
    379     }
    380     const jboolean is_playing = mp->isPlaying();
    381 
    382     LOGV("isPlaying: %d", is_playing);
    383     return is_playing;
    384 }
    385 
    386 static void
    387 android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, int msec)
    388 {
    389     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    390     if (mp == NULL ) {
    391         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    392         return;
    393     }
    394     LOGV("seekTo: %d(msec)", msec);
    395     process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
    396 }
    397 
    398 static int
    399 android_media_MediaPlayer_getVideoWidth(JNIEnv *env, jobject thiz)
    400 {
    401     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    402     if (mp == NULL ) {
    403         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    404         return 0;
    405     }
    406     int w;
    407     if (0 != mp->getVideoWidth(&w)) {
    408         LOGE("getVideoWidth failed");
    409         w = 0;
    410     }
    411     LOGV("getVideoWidth: %d", w);
    412     return w;
    413 }
    414 
    415 static int
    416 android_media_MediaPlayer_getVideoHeight(JNIEnv *env, jobject thiz)
    417 {
    418     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    419     if (mp == NULL ) {
    420         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    421         return 0;
    422     }
    423     int h;
    424     if (0 != mp->getVideoHeight(&h)) {
    425         LOGE("getVideoHeight failed");
    426         h = 0;
    427     }
    428     LOGV("getVideoHeight: %d", h);
    429     return h;
    430 }
    431 
    432 
    433 static int
    434 android_media_MediaPlayer_getCurrentPosition(JNIEnv *env, jobject thiz)
    435 {
    436     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    437     if (mp == NULL ) {
    438         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    439         return 0;
    440     }
    441     int msec;
    442     process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
    443     LOGV("getCurrentPosition: %d (msec)", msec);
    444     return msec;
    445 }
    446 
    447 static int
    448 android_media_MediaPlayer_getDuration(JNIEnv *env, jobject thiz)
    449 {
    450     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    451     if (mp == NULL ) {
    452         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    453         return 0;
    454     }
    455     int msec;
    456     process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
    457     LOGV("getDuration: %d (msec)", msec);
    458     return msec;
    459 }
    460 
    461 static void
    462 android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
    463 {
    464     LOGV("reset");
    465     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    466     if (mp == NULL ) {
    467         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    468         return;
    469     }
    470     process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
    471 }
    472 
    473 static void
    474 android_media_MediaPlayer_setAudioStreamType(JNIEnv *env, jobject thiz, int streamtype)
    475 {
    476     LOGV("setAudioStreamType: %d", streamtype);
    477     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    478     if (mp == NULL ) {
    479         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    480         return;
    481     }
    482     process_media_player_call( env, thiz, mp->setAudioStreamType(streamtype) , NULL, NULL );
    483 }
    484 
    485 static void
    486 android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
    487 {
    488     LOGV("setLooping: %d", looping);
    489     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    490     if (mp == NULL ) {
    491         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    492         return;
    493     }
    494     process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
    495 }
    496 
    497 static jboolean
    498 android_media_MediaPlayer_isLooping(JNIEnv *env, jobject thiz)
    499 {
    500     LOGV("isLooping");
    501     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    502     if (mp == NULL ) {
    503         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    504         return false;
    505     }
    506     return mp->isLooping();
    507 }
    508 
    509 static void
    510 android_media_MediaPlayer_setVolume(JNIEnv *env, jobject thiz, float leftVolume, float rightVolume)
    511 {
    512     LOGV("setVolume: left %f  right %f", leftVolume, rightVolume);
    513     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    514     if (mp == NULL ) {
    515         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    516         return;
    517     }
    518     process_media_player_call( env, thiz, mp->setVolume(leftVolume, rightVolume), NULL, NULL );
    519 }
    520 
    521 // FIXME: deprecated
    522 static jobject
    523 android_media_MediaPlayer_getFrameAt(JNIEnv *env, jobject thiz, jint msec)
    524 {
    525     return NULL;
    526 }
    527 
    528 
    529 // Sends the request and reply parcels to the media player via the
    530 // binder interface.
    531 static jint
    532 android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
    533                                  jobject java_request, jobject java_reply)
    534 {
    535     sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    536     if (media_player == NULL ) {
    537         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    538         return UNKNOWN_ERROR;
    539     }
    540 
    541 
    542     Parcel *request = parcelForJavaObject(env, java_request);
    543     Parcel *reply = parcelForJavaObject(env, java_reply);
    544 
    545     // Don't use process_media_player_call which use the async loop to
    546     // report errors, instead returns the status.
    547     return media_player->invoke(*request, reply);
    548 }
    549 
    550 // Sends the new filter to the client.
    551 static jint
    552 android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
    553 {
    554     sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    555     if (media_player == NULL ) {
    556         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    557         return UNKNOWN_ERROR;
    558     }
    559 
    560     Parcel *filter = parcelForJavaObject(env, request);
    561 
    562     if (filter == NULL ) {
    563         jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
    564         return UNKNOWN_ERROR;
    565     }
    566 
    567     return media_player->setMetadataFilter(*filter);
    568 }
    569 
    570 static jboolean
    571 android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
    572                                       jboolean apply_filter, jobject reply)
    573 {
    574     sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    575     if (media_player == NULL ) {
    576         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    577         return false;
    578     }
    579 
    580     Parcel *metadata = parcelForJavaObject(env, reply);
    581 
    582     if (metadata == NULL ) {
    583         jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
    584         return false;
    585     }
    586 
    587     metadata->freeData();
    588     // On return metadata is positioned at the beginning of the
    589     // metadata. Note however that the parcel actually starts with the
    590     // return code so you should not rewind the parcel using
    591     // setDataPosition(0).
    592     return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
    593 }
    594 
    595 // This function gets some field IDs, which in turn causes class initialization.
    596 // It is called from a static block in MediaPlayer, which won't run until the
    597 // first time an instance of this class is used.
    598 static void
    599 android_media_MediaPlayer_native_init(JNIEnv *env)
    600 {
    601     jclass clazz;
    602 
    603     clazz = env->FindClass("android/media/MediaPlayer");
    604     if (clazz == NULL) {
    605         return;
    606     }
    607 
    608     fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
    609     if (fields.context == NULL) {
    610         return;
    611     }
    612 
    613     fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
    614                                                "(Ljava/lang/Object;IIILjava/lang/Object;)V");
    615     if (fields.post_event == NULL) {
    616         return;
    617     }
    618 
    619     fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
    620     if (fields.surface_texture == NULL) {
    621         return;
    622     }
    623 }
    624 
    625 static void
    626 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
    627 {
    628     LOGV("native_setup");
    629     sp<MediaPlayer> mp = new MediaPlayer();
    630     if (mp == NULL) {
    631         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
    632         return;
    633     }
    634 
    635     // create new listener and give it to MediaPlayer
    636     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
    637     mp->setListener(listener);
    638 
    639     // Stow our new C++ MediaPlayer in an opaque field in the Java object.
    640     setMediaPlayer(env, thiz, mp);
    641 }
    642 
    643 static void
    644 android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
    645 {
    646     LOGV("release");
    647     decVideoSurfaceRef(env, thiz);
    648     sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
    649     if (mp != NULL) {
    650         // this prevents native callbacks after the object is released
    651         mp->setListener(0);
    652         mp->disconnect();
    653     }
    654 }
    655 
    656 static void
    657 android_media_MediaPlayer_native_finalize(JNIEnv *env, jobject thiz)
    658 {
    659     LOGV("native_finalize");
    660     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    661     if (mp != NULL) {
    662         LOGW("MediaPlayer finalized without being released");
    663     }
    664     android_media_MediaPlayer_release(env, thiz);
    665 }
    666 
    667 static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env,  jobject thiz, jint sessionId) {
    668     LOGV("set_session_id(): %d", sessionId);
    669     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    670     if (mp == NULL ) {
    671         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    672         return;
    673     }
    674     process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
    675 }
    676 
    677 static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env,  jobject thiz) {
    678     LOGV("get_session_id()");
    679     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    680     if (mp == NULL ) {
    681         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    682         return 0;
    683     }
    684 
    685     return mp->getAudioSessionId();
    686 }
    687 
    688 static void
    689 android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
    690 {
    691     LOGV("setAuxEffectSendLevel: level %f", level);
    692     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    693     if (mp == NULL ) {
    694         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    695         return;
    696     }
    697     process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
    698 }
    699 
    700 static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env,  jobject thiz, jint effectId) {
    701     LOGV("attachAuxEffect(): %d", effectId);
    702     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    703     if (mp == NULL ) {
    704         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    705         return;
    706     }
    707     process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
    708 }
    709 
    710 static jint
    711 android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
    712 {
    713     sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
    714     sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
    715     if (service.get() == NULL) {
    716         jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService");
    717         return UNKNOWN_ERROR;
    718     }
    719 
    720     Parcel *reply = parcelForJavaObject(env, java_reply);
    721 
    722     return service->pullBatteryData(reply);
    723 }
    724 
    725 static jboolean
    726 android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
    727 {
    728     LOGV("setParameter: key %d", key);
    729     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    730     if (mp == NULL ) {
    731         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    732         return false;
    733     }
    734 
    735     Parcel *request = parcelForJavaObject(env, java_request);
    736     status_t err = mp->setParameter(key, *request);
    737     if (err == OK) {
    738         return true;
    739     } else {
    740         return false;
    741     }
    742 }
    743 
    744 static void
    745 android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobject java_reply)
    746 {
    747     LOGV("getParameter: key %d", key);
    748     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    749     if (mp == NULL ) {
    750         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    751         return;
    752     }
    753 
    754     Parcel *reply = parcelForJavaObject(env, java_reply);
    755     process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL );
    756 }
    757 
    758 // ----------------------------------------------------------------------------
    759 
    760 static JNINativeMethod gMethods[] = {
    761     {"setDataSource",       "(Ljava/lang/String;)V",            (void *)android_media_MediaPlayer_setDataSource},
    762 
    763     {
    764         "_setDataSource",
    765         "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
    766         (void *)android_media_MediaPlayer_setDataSourceAndHeaders
    767     },
    768 
    769     {"setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
    770     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
    771     {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},
    772     {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
    773     {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},
    774     {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},
    775     {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer_getVideoWidth},
    776     {"getVideoHeight",      "()I",                              (void *)android_media_MediaPlayer_getVideoHeight},
    777     {"seekTo",              "(I)V",                             (void *)android_media_MediaPlayer_seekTo},
    778     {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},
    779     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},
    780     {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},
    781     {"getDuration",         "()I",                              (void *)android_media_MediaPlayer_getDuration},
    782     {"_release",            "()V",                              (void *)android_media_MediaPlayer_release},
    783     {"_reset",              "()V",                              (void *)android_media_MediaPlayer_reset},
    784     {"setAudioStreamType",  "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},
    785     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},
    786     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},
    787     {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},
    788     {"getFrameAt",          "(I)Landroid/graphics/Bitmap;",     (void *)android_media_MediaPlayer_getFrameAt},
    789     {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
    790     {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
    791     {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
    792     {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},
    793     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    794     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
    795     {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},
    796     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},
    797     {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
    798     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer_attachAuxEffect},
    799     {"native_pullBatteryData", "(Landroid/os/Parcel;)I",        (void *)android_media_MediaPlayer_pullBatteryData},
    800     {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_setParameter},
    801     {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},
    802 };
    803 
    804 static const char* const kClassPathName = "android/media/MediaPlayer";
    805 
    806 // This function only registers the native methods
    807 static int register_android_media_MediaPlayer(JNIEnv *env)
    808 {
    809     return AndroidRuntime::registerNativeMethods(env,
    810                 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
    811 }
    812 
    813 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
    814 extern int register_android_media_MediaRecorder(JNIEnv *env);
    815 extern int register_android_media_MediaScanner(JNIEnv *env);
    816 extern int register_android_media_ResampleInputStream(JNIEnv *env);
    817 extern int register_android_media_MediaProfiles(JNIEnv *env);
    818 extern int register_android_media_AmrInputStream(JNIEnv *env);
    819 extern int register_android_mtp_MtpDatabase(JNIEnv *env);
    820 extern int register_android_mtp_MtpDevice(JNIEnv *env);
    821 extern int register_android_mtp_MtpServer(JNIEnv *env);
    822 
    823 jint JNI_OnLoad(JavaVM* vm, void* reserved)
    824 {
    825     JNIEnv* env = NULL;
    826     jint result = -1;
    827 
    828     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    829         LOGE("ERROR: GetEnv failed
    ");
    830         goto bail;
    831     }
    832     assert(env != NULL);
    833 
    834     if (register_android_media_MediaPlayer(env) < 0) {
    835         LOGE("ERROR: MediaPlayer native registration failed
    ");
    836         goto bail;
    837     }
    838 
    839     if (register_android_media_MediaRecorder(env) < 0) {
    840         LOGE("ERROR: MediaRecorder native registration failed
    ");
    841         goto bail;
    842     }
    843 
    844     if (register_android_media_MediaScanner(env) < 0) {
    845         LOGE("ERROR: MediaScanner native registration failed
    ");
    846         goto bail;
    847     }
    848 
    849     if (register_android_media_MediaMetadataRetriever(env) < 0) {
    850         LOGE("ERROR: MediaMetadataRetriever native registration failed
    ");
    851         goto bail;
    852     }
    853 
    854     if (register_android_media_AmrInputStream(env) < 0) {
    855         LOGE("ERROR: AmrInputStream native registration failed
    ");
    856         goto bail;
    857     }
    858 
    859     if (register_android_media_ResampleInputStream(env) < 0) {
    860         LOGE("ERROR: ResampleInputStream native registration failed
    ");
    861         goto bail;
    862     }
    863 
    864     if (register_android_media_MediaProfiles(env) < 0) {
    865         LOGE("ERROR: MediaProfiles native registration failed");
    866         goto bail;
    867     }
    868 
    869     if (register_android_mtp_MtpDatabase(env) < 0) {
    870         LOGE("ERROR: MtpDatabase native registration failed");
    871         goto bail;
    872     }
    873 
    874     if (register_android_mtp_MtpDevice(env) < 0) {
    875         LOGE("ERROR: MtpDevice native registration failed");
    876         goto bail;
    877     }
    878 
    879     if (register_android_mtp_MtpServer(env) < 0) {
    880         LOGE("ERROR: MtpServer native registration failed");
    881         goto bail;
    882     }
    883 
    884     /** success -- return valid version number */
    885     result = JNI_VERSION_1_4;
    886 
    887 bail:
    888     return result;
    889 }
    890 
    891 // KTHXBYE
    View Code
  • what happend when new a MediaPlayer
  •  1 static void android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
     2 {
     3     LOGV("native_setup");
     4     sp<MediaPlayer> mp = new MediaPlayer();
     5     if (mp == NULL) {
     6         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
     7         return;
     8     }    
     9     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
    10     mp->setListener(listener);
    11     setMediaPlayer(env, thiz, mp);
    12 }
  •  1 static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
     2 {
     3     Mutex::Autolock l(sLock);
     4     sp<MediaPlayer> old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
     5     if (player.get()) {
     6         player->incStrong(thiz);
     7     }
     8     if (old != 0) {
     9         old->decStrong(thiz);
    10     }
    11     env->SetIntField(thiz, fields.context, (int)player.get());
    12     return old;
    13 }
  •  1 static void
     2 android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
     3 {
     4     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     5     if (mp == NULL ) {
     6         jniThrowException(env, "java/lang/IllegalStateException", NULL);
     7         return;
     8     }
     9     if (fileDescriptor == NULL) {
    10         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    11         return;
    12     }
    13     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    14     LOGV("setDataSourceFD: fd %d", fd);
    15     process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
    16 }
  •  1 status_t MediaPlayer::setDataSource(
     2         const char *url, const KeyedVector<String8, String8> *headers)
     3 {
     4     LOGV("setDataSource(%s)", url);
     5     status_t err = BAD_VALUE;
     6     if (url != NULL) {
     7         const sp<IMediaPlayerService>& service(getMediaPlayerService());//now we got a mediaPlayerService
     8         if (service != 0) {
     9             sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
    10             if (NO_ERROR != player->setDataSource(url, headers)) {
    11                 player.clear();
    12             }
    13             err = attachNewPlayer(player);
    14         }
    15     }
    16     return err;
    17 }
  •  1 const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
     2 {
     3     LOGV("getMediaPlayerService");
     4     Mutex::Autolock _l(sServiceLock);
     5     if (sMediaPlayerService.get() == 0) {
     6         sp<IServiceManager> sm = defaultServiceManager(); //get media player serice from service manager
     7         sp<IBinder> binder;
     8         do {
     9             binder = sm->getService(String16("media.player"));
    10             if (binder != 0) {
    11                 break;
    12              }
    13              LOGW("Media player service not published, waiting...");
    14              usleep(500000); // 0.5 s
    15         } while(true);
    16 
    17         if (sDeathNotifier == NULL) {
    18         sDeathNotifier = new DeathNotifier();
    19     }
    20     binder->linkToDeath(sDeathNotifier);
    21     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);Now we have BpMediaPlayer object
    22     }
    23     LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    24     return sMediaPlayerService;
    25 }
  • what happend when prepare
  •  1 static void android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
     2 {
     3     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     4     if (mp == NULL ) {
     5         jniThrowException(env, "java/lang/IllegalStateException", NULL);
     6         return;
     7     }
     8     sp<ISurfaceTexture> st = getVideoSurfaceTexture(env, thiz);
     9     mp->setVideoSurfaceTexture(st);
    10     process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
    11 }
  • start on media player
  •  1 static void android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
     2 {
     3     LOGV("start");
     4     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     5     if (mp == NULL ) {
     6         jniThrowException(env, "java/lang/IllegalStateException", NULL);
     7         return;
     8     }
     9     process_media_player_call( env, thiz, mp->start(), NULL, NULL );
    10 }
  • process of command send to mediaPlayer
  •  1 static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
     2 {
     3     if (exception == NULL) {  // Don't throw exception. Instead, send an event.
     4         if (opStatus != (status_t) OK) {
     5             sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     6             if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
     7         }
     8     } else {  // Throw exception!
     9         if ( opStatus == (status_t) INVALID_OPERATION ) {
    10             jniThrowException(env, "java/lang/IllegalStateException", NULL);
    11         } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
    12             jniThrowException(env, "java/lang/SecurityException", NULL);
    13         } else if ( opStatus != (status_t) OK ) {
    14             if (strlen(message) > 230) {               
    15                jniThrowException( env, exception, message);
    16             } else {
    17                char msg[256];                
    18                sprintf(msg, "%s: status=0x%X", message, opStatus);
    19                jniThrowException( env, exception, msg);
    20             }
    21         }
    22     }
    23 }
  • How to get media player
  • 1 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
    2 {
    3     Mutex::Autolock l(sLock);
    4     MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);
    5     return sp<MediaPlayer>(p);
    6 }
  • The methods in MediaPlayer.cpp
  •  1 status_t MediaPlayer::start()
     2 {
     3     LOGV("start");
     4     Mutex::Autolock _l(mLock);
     5     if (mCurrentState & MEDIA_PLAYER_STARTED)
     6         return NO_ERROR;
     7     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
     8                     MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
     9         mPlayer->setLooping(mLoop);
    10         mPlayer->setVolume(mLeftVolume, mRightVolume);
    11         mPlayer->setAuxEffectSendLevel(mSendLevel);
    12         mCurrentState = MEDIA_PLAYER_STARTED;
    13         status_t ret = mPlayer->start(); //now call BpMediaPlayer.start()
    14         if (ret != NO_ERROR) {
    15             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    16         } else {
    17             if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
    18                 LOGV("playback completed immediately following start()");
    19             }
    20         }
    21         return ret;
    22     }
    23     LOGE("start called in state %d", mCurrentState);
    24     return INVALID_OPERATION;
    25 }
  • BpMediaPlayer
  •   1 /**
      2 **
      3 ** Copyright 2008, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <binder/Parcel.h>
     22 
     23 #include <media/IMediaPlayer.h>
     24 #include <media/IStreamSource.h>
     25 
     26 #include <surfaceflinger/ISurface.h>
     27 #include <surfaceflinger/Surface.h>
     28 #include <gui/ISurfaceTexture.h>
     29 #include <utils/String8.h>
     30 
     31 namespace android {
     32 
     33 enum {
     34     DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
     35     SET_DATA_SOURCE_URL,
     36     SET_DATA_SOURCE_FD,
     37     SET_DATA_SOURCE_STREAM,
     38     SET_VIDEO_SURFACE,
     39     PREPARE_ASYNC,
     40     START,
     41     STOP,
     42     IS_PLAYING,
     43     PAUSE,
     44     SEEK_TO,
     45     GET_CURRENT_POSITION,
     46     GET_DURATION,
     47     RESET,
     48     SET_AUDIO_STREAM_TYPE,
     49     SET_LOOPING,
     50     SET_VOLUME,
     51     INVOKE,
     52     SET_METADATA_FILTER,
     53     GET_METADATA,
     54     SET_AUX_EFFECT_SEND_LEVEL,
     55     ATTACH_AUX_EFFECT,
     56     SET_VIDEO_SURFACETEXTURE,
     57     SET_PARAMETER,
     58     GET_PARAMETER,
     59 };
     60 
     61 class BpMediaPlayer: public BpInterface<IMediaPlayer>
     62 {
     63 public:
     64     BpMediaPlayer(const sp<IBinder>& impl)
     65         : BpInterface<IMediaPlayer>(impl)
     66     {
     67     }
     68 
     69     // disconnect from media player service
     70     void disconnect()
     71     {
     72         Parcel data, reply;
     73         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
     74         remote()->transact(DISCONNECT, data, &reply);
     75     }
     76 
     77     status_t setDataSource(const char* url,
     78             const KeyedVector<String8, String8>* headers)
     79     {
     80         Parcel data, reply;
     81         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
     82         data.writeCString(url);
     83         if (headers == NULL) {
     84             data.writeInt32(0);
     85         } else {
     86             // serialize the headers
     87             data.writeInt32(headers->size());
     88             for (size_t i = 0; i < headers->size(); ++i) {
     89                 data.writeString8(headers->keyAt(i));
     90                 data.writeString8(headers->valueAt(i));
     91             }
     92         }
     93         remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
     94         return reply.readInt32();
     95     }
     96 
     97     status_t setDataSource(int fd, int64_t offset, int64_t length) {
     98         Parcel data, reply;
     99         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    100         data.writeFileDescriptor(fd);
    101         data.writeInt64(offset);
    102         data.writeInt64(length);
    103         remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
    104         return reply.readInt32();
    105     }
    106 
    107     status_t setDataSource(const sp<IStreamSource> &source) {
    108         Parcel data, reply;
    109         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    110         data.writeStrongBinder(source->asBinder());
    111         remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
    112         return reply.readInt32();
    113     }
    114 
    115     // pass the buffered Surface to the media player service
    116     status_t setVideoSurface(const sp<Surface>& surface)
    117     {
    118         Parcel data, reply;
    119         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    120         Surface::writeToParcel(surface, &data);
    121         remote()->transact(SET_VIDEO_SURFACE, data, &reply);
    122         return reply.readInt32();
    123     }
    124 
    125     // pass the buffered ISurfaceTexture to the media player service
    126     status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
    127     {
    128         Parcel data, reply;
    129         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    130         sp<IBinder> b(surfaceTexture->asBinder());
    131         data.writeStrongBinder(b);
    132         remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
    133         return reply.readInt32();
    134     }
    135 
    136     status_t prepareAsync()
    137     {
    138         Parcel data, reply;
    139         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    140         remote()->transact(PREPARE_ASYNC, data, &reply);
    141         return reply.readInt32();
    142     }
    143 
    144     status_t start()
    145     {
    146         Parcel data, reply;
    147         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    148         remote()->transact(START, data, &reply);
    149         return reply.readInt32();
    150     }
    151 
    152     status_t stop()
    153     {
    154         Parcel data, reply;
    155         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    156         remote()->transact(STOP, data, &reply);
    157         return reply.readInt32();
    158     }
    159 
    160     status_t isPlaying(bool* state)
    161     {
    162         Parcel data, reply;
    163         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    164         remote()->transact(IS_PLAYING, data, &reply);
    165         *state = reply.readInt32();
    166         return reply.readInt32();
    167     }
    168 
    169     status_t pause()
    170     {
    171         Parcel data, reply;
    172         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    173         remote()->transact(PAUSE, data, &reply);
    174         return reply.readInt32();
    175     }
    176 
    177     status_t seekTo(int msec)
    178     {
    179         Parcel data, reply;
    180         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    181         data.writeInt32(msec);
    182         remote()->transact(SEEK_TO, data, &reply);
    183         return reply.readInt32();
    184     }
    185 
    186     status_t getCurrentPosition(int* msec)
    187     {
    188         Parcel data, reply;
    189         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    190         remote()->transact(GET_CURRENT_POSITION, data, &reply);
    191         *msec = reply.readInt32();
    192         return reply.readInt32();
    193     }
    194 
    195     status_t getDuration(int* msec)
    196     {
    197         Parcel data, reply;
    198         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    199         remote()->transact(GET_DURATION, data, &reply);
    200         *msec = reply.readInt32();
    201         return reply.readInt32();
    202     }
    203 
    204     status_t reset()
    205     {
    206         Parcel data, reply;
    207         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    208         remote()->transact(RESET, data, &reply);
    209         return reply.readInt32();
    210     }
    211 
    212     status_t setAudioStreamType(int type)
    213     {
    214         Parcel data, reply;
    215         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    216         data.writeInt32(type);
    217         remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
    218         return reply.readInt32();
    219     }
    220 
    221     status_t setLooping(int loop)
    222     {
    223         Parcel data, reply;
    224         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    225         data.writeInt32(loop);
    226         remote()->transact(SET_LOOPING, data, &reply);
    227         return reply.readInt32();
    228     }
    229 
    230     status_t setVolume(float leftVolume, float rightVolume)
    231     {
    232         Parcel data, reply;
    233         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    234         data.writeFloat(leftVolume);
    235         data.writeFloat(rightVolume);
    236         remote()->transact(SET_VOLUME, data, &reply);
    237         return reply.readInt32();
    238     }
    239 
    240     status_t invoke(const Parcel& request, Parcel *reply)
    241     {
    242         // Avoid doing any extra copy. The interface descriptor should
    243         // have been set by MediaPlayer.java.
    244         return remote()->transact(INVOKE, request, reply);
    245     }
    246 
    247     status_t setMetadataFilter(const Parcel& request)
    248     {
    249         Parcel reply;
    250         // Avoid doing any extra copy of the request. The interface
    251         // descriptor should have been set by MediaPlayer.java.
    252         remote()->transact(SET_METADATA_FILTER, request, &reply);
    253         return reply.readInt32();
    254     }
    255 
    256     status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
    257     {
    258         Parcel request;
    259         request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    260         // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
    261         request.writeInt32(update_only);
    262         request.writeInt32(apply_filter);
    263         remote()->transact(GET_METADATA, request, reply);
    264         return reply->readInt32();
    265     }
    266 
    267     status_t setAuxEffectSendLevel(float level)
    268     {
    269         Parcel data, reply;
    270         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    271         data.writeFloat(level);
    272         remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
    273         return reply.readInt32();
    274     }
    275 
    276     status_t attachAuxEffect(int effectId)
    277     {
    278         Parcel data, reply;
    279         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    280         data.writeInt32(effectId);
    281         remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
    282         return reply.readInt32();
    283     }
    284 
    285     status_t setParameter(int key, const Parcel& request)
    286     {
    287         Parcel data, reply;
    288         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    289         data.writeInt32(key);
    290         if (request.dataSize() > 0) {
    291             data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
    292         }
    293         remote()->transact(SET_PARAMETER, data, &reply);
    294         return reply.readInt32();
    295     }
    296 
    297     status_t getParameter(int key, Parcel *reply)
    298     {
    299         Parcel data;
    300         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    301         data.writeInt32(key);
    302         return remote()->transact(GET_PARAMETER, data, reply);
    303     }
    304 
    305 };
    306 
    307 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
    308 
    309 // ----------------------------------------------------------------------
    310 
    311 status_t BnMediaPlayer::onTransact(
    312     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    313 {
    314     switch(code) {
    315         case DISCONNECT: {
    316             CHECK_INTERFACE(IMediaPlayer, data, reply);
    317             disconnect();
    318             return NO_ERROR;
    319         } break;
    320         case SET_DATA_SOURCE_URL: {
    321             CHECK_INTERFACE(IMediaPlayer, data, reply);
    322             const char* url = data.readCString();
    323             KeyedVector<String8, String8> headers;
    324             int32_t numHeaders = data.readInt32();
    325             for (int i = 0; i < numHeaders; ++i) {
    326                 String8 key = data.readString8();
    327                 String8 value = data.readString8();
    328                 headers.add(key, value);
    329             }
    330             reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers : NULL));
    331             return NO_ERROR;
    332         } break;
    333         case SET_DATA_SOURCE_FD: {
    334             CHECK_INTERFACE(IMediaPlayer, data, reply);
    335             int fd = data.readFileDescriptor();
    336             int64_t offset = data.readInt64();
    337             int64_t length = data.readInt64();
    338             reply->writeInt32(setDataSource(fd, offset, length));
    339             return NO_ERROR;
    340         }
    341         case SET_DATA_SOURCE_STREAM: {
    342             CHECK_INTERFACE(IMediaPlayer, data, reply);
    343             sp<IStreamSource> source =
    344                 interface_cast<IStreamSource>(data.readStrongBinder());
    345             reply->writeInt32(setDataSource(source));
    346             return NO_ERROR;
    347         }
    348         case SET_VIDEO_SURFACE: {
    349             CHECK_INTERFACE(IMediaPlayer, data, reply);
    350             sp<Surface> surface = Surface::readFromParcel(data);
    351             reply->writeInt32(setVideoSurface(surface));
    352             return NO_ERROR;
    353         } break;
    354         case SET_VIDEO_SURFACETEXTURE: {
    355             CHECK_INTERFACE(IMediaPlayer, data, reply);
    356             sp<ISurfaceTexture> surfaceTexture =
    357                     interface_cast<ISurfaceTexture>(data.readStrongBinder());
    358             reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
    359             return NO_ERROR;
    360         } break;
    361         case PREPARE_ASYNC: {
    362             CHECK_INTERFACE(IMediaPlayer, data, reply);
    363             reply->writeInt32(prepareAsync());
    364             return NO_ERROR;
    365         } break;
    366         case START: {
    367             CHECK_INTERFACE(IMediaPlayer, data, reply);
    368             reply->writeInt32(start());
    369             return NO_ERROR;
    370         } break;
    371         case STOP: {
    372             CHECK_INTERFACE(IMediaPlayer, data, reply);
    373             reply->writeInt32(stop());
    374             return NO_ERROR;
    375         } break;
    376         case IS_PLAYING: {
    377             CHECK_INTERFACE(IMediaPlayer, data, reply);
    378             bool state;
    379             status_t ret = isPlaying(&state);
    380             reply->writeInt32(state);
    381             reply->writeInt32(ret);
    382             return NO_ERROR;
    383         } break;
    384         case PAUSE: {
    385             CHECK_INTERFACE(IMediaPlayer, data, reply);
    386             reply->writeInt32(pause());
    387             return NO_ERROR;
    388         } break;
    389         case SEEK_TO: {
    390             CHECK_INTERFACE(IMediaPlayer, data, reply);
    391             reply->writeInt32(seekTo(data.readInt32()));
    392             return NO_ERROR;
    393         } break;
    394         case GET_CURRENT_POSITION: {
    395             CHECK_INTERFACE(IMediaPlayer, data, reply);
    396             int msec;
    397             status_t ret = getCurrentPosition(&msec);
    398             reply->writeInt32(msec);
    399             reply->writeInt32(ret);
    400             return NO_ERROR;
    401         } break;
    402         case GET_DURATION: {
    403             CHECK_INTERFACE(IMediaPlayer, data, reply);
    404             int msec;
    405             status_t ret = getDuration(&msec);
    406             reply->writeInt32(msec);
    407             reply->writeInt32(ret);
    408             return NO_ERROR;
    409         } break;
    410         case RESET: {
    411             CHECK_INTERFACE(IMediaPlayer, data, reply);
    412             reply->writeInt32(reset());
    413             return NO_ERROR;
    414         } break;
    415         case SET_AUDIO_STREAM_TYPE: {
    416             CHECK_INTERFACE(IMediaPlayer, data, reply);
    417             reply->writeInt32(setAudioStreamType(data.readInt32()));
    418             return NO_ERROR;
    419         } break;
    420         case SET_LOOPING: {
    421             CHECK_INTERFACE(IMediaPlayer, data, reply);
    422             reply->writeInt32(setLooping(data.readInt32()));
    423             return NO_ERROR;
    424         } break;
    425         case SET_VOLUME: {
    426             CHECK_INTERFACE(IMediaPlayer, data, reply);
    427             float leftVolume = data.readFloat();
    428             float rightVolume = data.readFloat();
    429             reply->writeInt32(setVolume(leftVolume, rightVolume));
    430             return NO_ERROR;
    431         } break;
    432         case INVOKE: {
    433             CHECK_INTERFACE(IMediaPlayer, data, reply);
    434             status_t result = invoke(data, reply);
    435             return result;
    436         } break;
    437         case SET_METADATA_FILTER: {
    438             CHECK_INTERFACE(IMediaPlayer, data, reply);
    439             reply->writeInt32(setMetadataFilter(data));
    440             return NO_ERROR;
    441         } break;
    442         case GET_METADATA: {
    443             CHECK_INTERFACE(IMediaPlayer, data, reply);
    444             bool update_only = static_cast<bool>(data.readInt32());
    445             bool apply_filter = static_cast<bool>(data.readInt32());
    446             const status_t retcode = getMetadata(update_only, apply_filter, reply);
    447             reply->setDataPosition(0);
    448             reply->writeInt32(retcode);
    449             reply->setDataPosition(0);
    450             return NO_ERROR;
    451         } break;
    452         case SET_AUX_EFFECT_SEND_LEVEL: {
    453             CHECK_INTERFACE(IMediaPlayer, data, reply);
    454             reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
    455             return NO_ERROR;
    456         } break;
    457         case ATTACH_AUX_EFFECT: {
    458             CHECK_INTERFACE(IMediaPlayer, data, reply);
    459             reply->writeInt32(attachAuxEffect(data.readInt32()));
    460             return NO_ERROR;
    461         } break;
    462         case SET_PARAMETER: {
    463             CHECK_INTERFACE(IMediaPlayer, data, reply);
    464             int key = data.readInt32();
    465 
    466             Parcel request;
    467             if (data.dataAvail() > 0) {
    468                 request.appendFrom(
    469                         const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
    470             }
    471             request.setDataPosition(0);
    472             reply->writeInt32(setParameter(key, request));
    473             return NO_ERROR;
    474         } break;
    475         case GET_PARAMETER: {
    476             CHECK_INTERFACE(IMediaPlayer, data, reply);
    477             return getParameter(data.readInt32(), reply);
    478         } break;
    479         default:
    480             return BBinder::onTransact(code, data, reply, flags);
    481     }
    482 }
    483 
    484 // ----------------------------------------------------------------------------
    485 
    486 }; // namespace android
    BpMediaPlayer
    1 status_t BpMediaPlayer::stop()
    2     {
    3         Parcel data, reply;
    4         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
    5         remote()->transact(STOP, data, &reply);
    6         return reply.readInt32();
    7     }
     1 class BpMediaPlayer: public BpInterface<IMediaPlayer>
     2 {
     3 public:
     4     BpMediaPlayer(const sp<IBinder>& impl)
     5         : BpInterface<IMediaPlayer>(impl)
     6     {
     7     }
     8     .........................
     9 }
    10 template<INTERFACE>
    11 class BpInterface : public INTERFACE, public BpRefBase
    12 {
    13 public:
    14       BpInterface(const sp<IBinder>& remote);
    15 protected:
    16     virtual IBinder*            onAsBinder();
    17 };
  •  Call BpBinder::transact()

           

 1 status_t BpBinder::transact(
 2     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 3 {
 4     // Once a binder has died, it will never come back to life.
 5     if (mAlive) {
 6         status_t status = 
 7                 IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
 8         if (status == DEAD_OBJECT) mAlive = 0;
 9         return status;
10     }
11     return DEAD_OBJECT;
12 }
13 status_t IPCThreadState::transact(int32_t handle,
14                                   uint32_t code, const Parcel& data,
15                                   Parcel* reply, uint32_t flags)
16 {
17     status_t err = data.errorCheck();
18     flags |= TF_ACCEPT_FDS;
19     IF_LOG_TRANSACTIONS() {
20         TextOutput::Bundle _b(alog);
21         alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
22             << handle << " / code " << TypeCode(code) << ": "
23             << indent << data << dedent << endl;
24     }    
25     if (err == NO_ERROR) {
26         LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
27             (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
28         err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
29     }
30     ................
31 }
32 status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
33     int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
34 {
35     binder_transaction_data tr;
36     tr.target.handle = handle;
37     tr.code = code;
38     tr.flags = binderFlags;
39     tr.cookie = 0;
40     tr.sender_pid = 0;
41     tr.sender_euid = 0;
42     
43     const status_t err = data.errorCheck();
44     if (err == NO_ERROR) {
45         tr.data_size = data.ipcDataSize();
46         tr.data.ptr.buffer = data.ipcData();
47         tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
48         tr.data.ptr.offsets = data.ipcObjects();
49     } else if (statusBuffer) {
50         tr.flags |= TF_STATUS_CODE;
51         *statusBuffer = err;
52         tr.data_size = sizeof(status_t);
53         tr.data.ptr.buffer = statusBuffer;
54         tr.offsets_size = 0;
55         tr.data.ptr.offsets = NULL;
56     } else {
57         return (mLastError = err);
58     }    
59     mOut.writeInt32(cmd);
60     mOut.write(&tr, sizeof(tr));    
61     return NO_ERROR;
62 }

 

CameraService

AudioPolicyService

Reference:http://www.cnblogs.com/eustoma/archive/2011/08/22/2415824.html

http://blog.csdn.net/eustoma/article/details/6706492

http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html

原文地址:https://www.cnblogs.com/iiiDragon/p/3282980.html