• 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

  • 相关阅读:
    XML的语法
    dell omsa 监控,Nrpe信号量泄露
    cx_Oracle 报错 Reason: image not found
    cx_Oracle 中文乱码问题解决
    High Memory in the Linux Kernel
    使用二分法查找mobile文件中区号归属地
    mysql 导出csv
    行删除按钮功能
    vsftp 根据用户设置
    安装zabbix报错configure: error: libcurl library not found
  • 原文地址:https://www.cnblogs.com/iiiDragon/p/3282980.html
Copyright © 2020-2023  润新知