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 }
-
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
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
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
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
- 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 };
-
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 };
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
- 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
- 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
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