blob: 5c4cfe21562aa084b27ba98d1ff8166a684b2dbb [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070019#include <binder/ProcessState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080020
21#include <utils/Atomic.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070022#include <binder/BpBinder.h>
23#include <binder/IPCThreadState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080024#include <utils/Log.h>
25#include <utils/String8.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070026#include <binder/IServiceManager.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080027#include <utils/String8.h>
28#include <utils/threads.h>
29
Mathias Agopian208059f2009-05-18 15:08:03 -070030#include <private/binder/binder_module.h>
31#include <private/binder/Static.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032
33#include <errno.h>
34#include <fcntl.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <unistd.h>
38#include <sys/ioctl.h>
39#include <sys/mman.h>
40#include <sys/stat.h>
Philip Cuadraa082fa82016-04-08 10:29:14 -070041#include <sys/types.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042
Ganesh Mahendran6ac7fb52017-03-03 09:41:14 +080043#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
Wale Ogunwale376b8222015-04-13 16:16:10 -070044#define DEFAULT_MAX_BINDER_THREADS 15
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Philip Cuadraa082fa82016-04-08 10:29:14 -070046// -------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080047
48namespace android {
Wale Ogunwale376b8222015-04-13 16:16:10 -070049
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050class PoolThread : public Thread
51{
52public:
Chih-Hung Hsiehe2347b72016-04-25 15:41:05 -070053 explicit PoolThread(bool isMain)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054 : mIsMain(isMain)
55 {
56 }
57
58protected:
59 virtual bool threadLoop()
60 {
61 IPCThreadState::self()->joinThreadPool(mIsMain);
62 return false;
63 }
64
65 const bool mIsMain;
66};
67
68sp<ProcessState> ProcessState::self()
69{
Mathias Agopiane8db8712012-04-16 19:30:56 -070070 Mutex::Autolock _l(gProcessMutex);
71 if (gProcess != NULL) {
72 return gProcess;
73 }
Martijn Coenen55d871c2017-03-21 15:56:40 -070074 gProcess = new ProcessState("/dev/binder");
75 return gProcess;
76}
77
78sp<ProcessState> ProcessState::initWithDriver(const char* driver)
79{
80 Mutex::Autolock _l(gProcessMutex);
81 if (gProcess != NULL) {
82 LOG_ALWAYS_FATAL("ProcessState was already initialized.");
83 }
84 gProcess = new ProcessState(driver);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080085 return gProcess;
86}
87
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080088void ProcessState::setContextObject(const sp<IBinder>& object)
89{
90 setContextObject(object, String16("default"));
91}
92
Colin Cross6f4f3ab2014-02-05 17:42:44 -080093sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080094{
Jeff Browne16986c2011-07-08 18:52:57 -070095 return getStrongProxyForHandle(0);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080096}
97
98void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
99{
100 AutoMutex _l(mLock);
101 mContexts.add(name, object);
102}
103
104sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
105{
106 mLock.lock();
107 sp<IBinder> object(
108 mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
109 mLock.unlock();
110
111 //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
112
113 if (object != NULL) return object;
114
115 // Don't attempt to retrieve contexts if we manage them
116 if (mManagesContexts) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000117 ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800118 String8(name).string());
119 return NULL;
120 }
121
122 IPCThreadState* ipc = IPCThreadState::self();
123 {
124 Parcel data, reply;
125 // no interface token on this magic transaction
126 data.writeString16(name);
127 data.writeStrongBinder(caller);
128 status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
129 if (result == NO_ERROR) {
130 object = reply.readStrongBinder();
131 }
132 }
133
134 ipc->flushCommands();
135
136 if (object != NULL) setContextObject(object, name);
137 return object;
138}
139
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800140void ProcessState::startThreadPool()
141{
142 AutoMutex _l(mLock);
143 if (!mThreadPoolStarted) {
144 mThreadPoolStarted = true;
145 spawnPooledThread(true);
146 }
147}
148
149bool ProcessState::isContextManager(void) const
150{
151 return mManagesContexts;
152}
153
154bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
155{
156 if (!mManagesContexts) {
157 AutoMutex _l(mLock);
158 mBinderContextCheckFunc = checkFunc;
159 mBinderContextUserData = userData;
Jeff Browne16986c2011-07-08 18:52:57 -0700160
161 int dummy = 0;
Jeff Browne16986c2011-07-08 18:52:57 -0700162 status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
Jeff Browne16986c2011-07-08 18:52:57 -0700163 if (result == 0) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800164 mManagesContexts = true;
Jeff Browne16986c2011-07-08 18:52:57 -0700165 } else if (result == -1) {
166 mBinderContextCheckFunc = NULL;
167 mBinderContextUserData = NULL;
Steve Blocke6f43dd2012-01-06 19:20:56 +0000168 ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800169 }
170 }
171 return mManagesContexts;
172}
173
174ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
175{
176 const size_t N=mHandleToObject.size();
177 if (N <= (size_t)handle) {
178 handle_entry e;
179 e.binder = NULL;
180 e.refs = NULL;
181 status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
182 if (err < NO_ERROR) return NULL;
183 }
184 return &mHandleToObject.editItemAt(handle);
185}
186
187sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
188{
189 sp<IBinder> result;
190
191 AutoMutex _l(mLock);
192
193 handle_entry* e = lookupHandleLocked(handle);
194
195 if (e != NULL) {
196 // We need to create a new BpBinder if there isn't currently one, OR we
197 // are unable to acquire a weak reference on this current one. See comment
198 // in getWeakProxyForHandle() for more info about this.
199 IBinder* b = e->binder;
200 if (b == NULL || !e->refs->attemptIncWeak(this)) {
Todd Poynora7b0f042013-06-18 17:25:37 -0700201 if (handle == 0) {
202 // Special case for context manager...
203 // The context manager is the only object for which we create
204 // a BpBinder proxy without already holding a reference.
205 // Perform a dummy transaction to ensure the context manager
206 // is registered before we create the first local reference
207 // to it (which will occur when creating the BpBinder).
208 // If a local reference is created for the BpBinder when the
209 // context manager is not present, the driver will fail to
210 // provide a reference to the context manager, but the
211 // driver API does not return status.
212 //
213 // Note that this is not race-free if the context manager
214 // dies while this code runs.
215 //
216 // TODO: add a driver API to wait for context manager, or
217 // stop special casing handle 0 for context manager and add
218 // a driver API to get a handle to the context manager with
219 // proper reference counting.
220
221 Parcel data;
222 status_t status = IPCThreadState::self()->transact(
223 0, IBinder::PING_TRANSACTION, data, NULL, 0);
224 if (status == DEAD_OBJECT)
225 return NULL;
226 }
227
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800228 b = new BpBinder(handle);
229 e->binder = b;
230 if (b) e->refs = b->getWeakRefs();
231 result = b;
232 } else {
233 // This little bit of nastyness is to allow us to add a primary
234 // reference to the remote proxy when this team doesn't have one
235 // but another team is sending the handle to us.
236 result.force_set(b);
237 e->refs->decWeak(this);
238 }
239 }
240
241 return result;
242}
243
244wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
245{
246 wp<IBinder> result;
247
248 AutoMutex _l(mLock);
249
250 handle_entry* e = lookupHandleLocked(handle);
251
252 if (e != NULL) {
253 // We need to create a new BpBinder if there isn't currently one, OR we
254 // are unable to acquire a weak reference on this current one. The
255 // attemptIncWeak() is safe because we know the BpBinder destructor will always
256 // call expungeHandle(), which acquires the same lock we are holding now.
257 // We need to do this because there is a race condition between someone
258 // releasing a reference on this BpBinder, and a new reference on its handle
259 // arriving from the driver.
260 IBinder* b = e->binder;
261 if (b == NULL || !e->refs->attemptIncWeak(this)) {
262 b = new BpBinder(handle);
263 result = b;
264 e->binder = b;
265 if (b) e->refs = b->getWeakRefs();
266 } else {
267 result = b;
268 e->refs->decWeak(this);
269 }
270 }
271
272 return result;
273}
274
275void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
276{
277 AutoMutex _l(mLock);
278
279 handle_entry* e = lookupHandleLocked(handle);
280
281 // This handle may have already been replaced with a new BpBinder
282 // (if someone failed the AttemptIncWeak() above); we don't want
283 // to overwrite it.
284 if (e && e->binder == binder) e->binder = NULL;
285}
286
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800287String8 ProcessState::makeBinderThreadName() {
288 int32_t s = android_atomic_add(1, &mThreadPoolSeq);
Philip Cuadraa082fa82016-04-08 10:29:14 -0700289 pid_t pid = getpid();
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800290 String8 name;
Philip Cuadraa082fa82016-04-08 10:29:14 -0700291 name.appendFormat("Binder:%d_%X", pid, s);
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800292 return name;
293}
294
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800295void ProcessState::spawnPooledThread(bool isMain)
296{
297 if (mThreadPoolStarted) {
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800298 String8 name = makeBinderThreadName();
299 ALOGV("Spawning new pooled thread, name=%s\n", name.string());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800300 sp<Thread> t = new PoolThread(isMain);
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800301 t->run(name.string());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800302 }
303}
304
Mathias Agopian1b80f792012-04-17 16:11:08 -0700305status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) {
306 status_t result = NO_ERROR;
Wale Ogunwale376b8222015-04-13 16:16:10 -0700307 if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) != -1) {
308 mMaxThreads = maxThreads;
309 } else {
Mathias Agopian1b80f792012-04-17 16:11:08 -0700310 result = -errno;
311 ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
312 }
313 return result;
314}
315
Mathias Agopiane3e43b32013-03-07 15:34:28 -0800316void ProcessState::giveThreadPoolName() {
317 androidSetThreadName( makeBinderThreadName().string() );
318}
319
Martijn Coenen55d871c2017-03-21 15:56:40 -0700320static int open_driver(const char *driver)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800321{
Martijn Coenen55d871c2017-03-21 15:56:40 -0700322 int fd = open(driver, O_RDWR | O_CLOEXEC);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800323 if (fd >= 0) {
Jin Wei78181df2012-10-18 17:00:48 +0800324 int vers = 0;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800325 status_t result = ioctl(fd, BINDER_VERSION, &vers);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800326 if (result == -1) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000327 ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800328 close(fd);
329 fd = -1;
330 }
331 if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
Greg Hartman67ac00f2017-01-03 16:54:59 -0800332 ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
333 vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800334 close(fd);
335 fd = -1;
336 }
Wale Ogunwale376b8222015-04-13 16:16:10 -0700337 size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800338 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
339 if (result == -1) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000340 ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800341 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800342 } else {
Martijn Coenen55d871c2017-03-21 15:56:40 -0700343 ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800344 }
345 return fd;
346}
347
Martijn Coenen55d871c2017-03-21 15:56:40 -0700348ProcessState::ProcessState(const char *driver)
349 : mDriverFD(open_driver(driver))
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800350 , mVMStart(MAP_FAILED)
Wale Ogunwale376b8222015-04-13 16:16:10 -0700351 , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
352 , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
353 , mExecutingThreadsCount(0)
354 , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
Colin Cross96e83222016-04-15 14:29:55 -0700355 , mStarvationStartTimeMs(0)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800356 , mManagesContexts(false)
357 , mBinderContextCheckFunc(NULL)
358 , mBinderContextUserData(NULL)
359 , mThreadPoolStarted(false)
360 , mThreadPoolSeq(1)
361{
362 if (mDriverFD >= 0) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800363 // mmap the binder, providing a chunk of virtual address space to receive transactions.
364 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
365 if (mVMStart == MAP_FAILED) {
366 // *sigh*
Steve Blocke6f43dd2012-01-06 19:20:56 +0000367 ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800368 close(mDriverFD);
369 mDriverFD = -1;
370 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800371 }
Jeff Browne16986c2011-07-08 18:52:57 -0700372
373 LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800374}
375
376ProcessState::~ProcessState()
377{
zhongjieff405782016-03-09 15:05:04 +0800378 if (mDriverFD >= 0) {
379 if (mVMStart != MAP_FAILED) {
380 munmap(mVMStart, BINDER_VM_SIZE);
381 }
382 close(mDriverFD);
383 }
384 mDriverFD = -1;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800385}
386
387}; // namespace android