zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Sqlserver 实际开发中表变量的用法
    Python Day 20 面向对象 (面向对象的组合用法,面向对象的三大特性
    Python Day 19 面向对象(初识面向对象)
    Python Day 18 常用模块(模块和包)
    Python Day 17 常用模块(常用模块一 时间模块,random模块,os模块,sys模块,序列化模块)
    Python Day 15 函数(递归函数、二分查找算法)
    Python Day 14 函数(内置函数,匿名函数(lambda表达式))
    Python Day 13 函数(迭代器,生成器,列表推导式,生成器表达式)
    Python Day 11 + Python Day 12 函数(函数名的应用,闭包,装饰器)
    Python Day 10 函数(名称空间,作用域,作用域链,加载顺序等; 函数的嵌套 global,nonlocal)
  • 原文地址:https://www.cnblogs.com/iiiDragon/p/3282980.html
Copyright © 2011-2022 走看看