blob: 24569fa6e9b15a5a2b39f7bc39ea15ffe2a05cc9 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
17package android.os;
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.util.Log;
20
21import java.io.FileDescriptor;
22import java.io.FileOutputStream;
23import java.io.IOException;
24import java.io.PrintWriter;
25import java.lang.ref.WeakReference;
26import java.lang.reflect.Modifier;
27
28/**
29 * Base class for a remotable object, the core part of a lightweight
30 * remote procedure call mechanism defined by {@link IBinder}.
31 * This class is an implementation of IBinder that provides
32 * the standard support creating a local implementation of such an object.
33 *
34 * <p>Most developers will not implement this class directly, instead using the
35 * <a href="{@docRoot}guide/developing/tools/aidl.html">aidl</a> tool to describe the desired
36 * interface, having it generate the appropriate Binder subclass. You can,
37 * however, derive directly from Binder to implement your own custom RPC
38 * protocol or simply instantiate a raw Binder object directly to use as a
39 * token that can be shared across processes.
40 *
41 * @see IBinder
42 */
43public class Binder implements IBinder {
44 /*
45 * Set this flag to true to detect anonymous, local or member classes
46 * that extend this Binder class and that are not static. These kind
47 * of classes can potentially create leaks.
48 */
49 private static final boolean FIND_POTENTIAL_LEAKS = false;
50 private static final String TAG = "Binder";
51
52 private int mObject;
53 private IInterface mOwner;
54 private String mDescriptor;
55
56 /**
57 * Return the ID of the process that sent you the current transaction
58 * that is being processed. This pid can be used with higher-level
59 * system services to determine its identity and check permissions.
60 * If the current thread is not currently executing an incoming transaction,
61 * then its own pid is returned.
62 */
63 public static final native int getCallingPid();
64
65 /**
66 * Return the ID of the user assigned to the process that sent you the
67 * current transaction that is being processed. This uid can be used with
68 * higher-level system services to determine its identity and check
69 * permissions. If the current thread is not currently executing an
70 * incoming transaction, then its own uid is returned.
71 */
72 public static final native int getCallingUid();
73
74 /**
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070075 * Reset the identity of the incoming IPC on the current thread. This can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 * be useful if, while handling an incoming call, you will be calling
77 * on interfaces of other objects that may be local to your process and
78 * need to do permission checks on the calls coming into them (so they
79 * will check the permission of your own local process, and not whatever
80 * process originally called you).
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070081 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 * @return Returns an opaque token that can be used to restore the
83 * original calling identity by passing it to
84 * {@link #restoreCallingIdentity(long)}.
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070085 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 * @see #getCallingPid()
87 * @see #getCallingUid()
88 * @see #restoreCallingIdentity(long)
89 */
90 public static final native long clearCallingIdentity();
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 /**
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070093 * Restore the identity of the incoming IPC on the current thread
94 * back to a previously identity that was returned by {@link
95 * #clearCallingIdentity}.
96 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 * @param token The opaque token that was previously returned by
98 * {@link #clearCallingIdentity}.
Brad Fitzpatricka0527f22010-03-25 20:40:34 -070099 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 * @see #clearCallingIdentity
101 */
102 public static final native void restoreCallingIdentity(long token);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700103
104 /**
105 * Sets the native thread-local StrictMode policy mask.
106 *
107 * <p>The StrictMode settings are kept in two places: a Java-level
108 * threadlocal for libcore/Dalvik, and a native threadlocal (set
109 * here) for propagation via Binder calls. This is a little
110 * unfortunate, but necessary to break otherwise more unfortunate
111 * dependencies either of Dalvik on Android, or Android
112 * native-only code on Dalvik.
113 *
114 * @see StrictMode
115 * @hide
116 */
117 public static final native void setThreadStrictModePolicy(int policyMask);
118
119 /**
120 * Gets the current native thread-local StrictMode policy mask.
121 *
122 * @see #setThreadStrictModePolicy
123 * @hide
124 */
125 public static final native int getThreadStrictModePolicy();
126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 /**
128 * Flush any Binder commands pending in the current thread to the kernel
129 * driver. This can be
130 * useful to call before performing an operation that may block for a long
131 * time, to ensure that any pending object references have been released
132 * in order to prevent the process from holding on to objects longer than
133 * it needs to.
134 */
135 public static final native void flushPendingCommands();
136
137 /**
138 * Add the calling thread to the IPC thread pool. This function does
139 * not return until the current process is exiting.
140 */
141 public static final native void joinThreadPool();
142
143 /**
144 * Default constructor initializes the object.
145 */
146 public Binder() {
147 init();
148
149 if (FIND_POTENTIAL_LEAKS) {
150 final Class<? extends Binder> klass = getClass();
151 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
152 (klass.getModifiers() & Modifier.STATIC) == 0) {
153 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
154 klass.getCanonicalName());
155 }
156 }
157 }
158
159 /**
160 * Convenience method for associating a specific interface with the Binder.
161 * After calling, queryLocalInterface() will be implemented for you
162 * to return the given owner IInterface when the corresponding
163 * descriptor is requested.
164 */
165 public void attachInterface(IInterface owner, String descriptor) {
166 mOwner = owner;
167 mDescriptor = descriptor;
168 }
169
170 /**
171 * Default implementation returns an empty interface name.
172 */
173 public String getInterfaceDescriptor() {
174 return mDescriptor;
175 }
176
177 /**
178 * Default implementation always returns true -- if you got here,
179 * the object is alive.
180 */
181 public boolean pingBinder() {
182 return true;
183 }
184
185 /**
186 * {@inheritDoc}
187 *
188 * Note that if you're calling on a local binder, this always returns true
189 * because your process is alive if you're calling it.
190 */
191 public boolean isBinderAlive() {
192 return true;
193 }
194
195 /**
196 * Use information supplied to attachInterface() to return the
197 * associated IInterface if it matches the requested
198 * descriptor.
199 */
200 public IInterface queryLocalInterface(String descriptor) {
201 if (mDescriptor.equals(descriptor)) {
202 return mOwner;
203 }
204 return null;
205 }
206
207 /**
208 * Default implementation is a stub that returns false. You will want
209 * to override this to do the appropriate unmarshalling of transactions.
210 *
211 * <p>If you want to call this, call transact().
212 */
213 protected boolean onTransact(int code, Parcel data, Parcel reply,
214 int flags) throws RemoteException {
215 if (code == INTERFACE_TRANSACTION) {
216 reply.writeString(getInterfaceDescriptor());
217 return true;
218 } else if (code == DUMP_TRANSACTION) {
219 ParcelFileDescriptor fd = data.readFileDescriptor();
220 String[] args = data.readStringArray();
221 if (fd != null) {
222 try {
223 dump(fd.getFileDescriptor(), args);
224 } finally {
225 try {
226 fd.close();
227 } catch (IOException e) {
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700228 // swallowed, not propagated back to the caller
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 }
230 }
231 }
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700232 // Write the StrictMode header.
233 if (reply != null) {
234 reply.writeNoException();
235 } else {
236 StrictMode.clearGatheredViolations();
237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 return true;
239 }
240 return false;
241 }
242
243 /**
244 * Implemented to call the more convenient version
245 * {@link #dump(FileDescriptor, PrintWriter, String[])}.
246 */
247 public void dump(FileDescriptor fd, String[] args) {
248 FileOutputStream fout = new FileOutputStream(fd);
249 PrintWriter pw = new PrintWriter(fout);
250 try {
251 dump(fd, pw, args);
252 } finally {
253 pw.flush();
254 }
255 }
256
257 /**
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700258 * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
259 * executes asynchronously.
260 */
261 public void dumpAsync(final FileDescriptor fd, final String[] args) {
262 final FileOutputStream fout = new FileOutputStream(fd);
263 final PrintWriter pw = new PrintWriter(fout);
264 Thread thr = new Thread("Binder.dumpAsync") {
265 public void run() {
266 try {
267 dump(fd, pw, args);
268 } finally {
269 pw.flush();
270 }
271 }
272 };
273 thr.start();
274 }
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * Print the object's state into the given stream.
278 *
279 * @param fd The raw file descriptor that the dump is being sent to.
280 * @param fout The file to which you should dump your state. This will be
281 * closed for you after you return.
282 * @param args additional arguments to the dump request.
283 */
284 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
285 }
286
287 /**
288 * Default implementation rewinds the parcels and calls onTransact. On
289 * the remote side, transact calls into the binder to do the IPC.
290 */
291 public final boolean transact(int code, Parcel data, Parcel reply,
292 int flags) throws RemoteException {
Joe Onorato43a17652011-04-06 19:22:23 -0700293 if (false) Log.v("Binder", "Transact: " + code + " to " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 if (data != null) {
295 data.setDataPosition(0);
296 }
297 boolean r = onTransact(code, data, reply, flags);
298 if (reply != null) {
299 reply.setDataPosition(0);
300 }
301 return r;
302 }
303
304 /**
305 * Local implementation is a no-op.
306 */
307 public void linkToDeath(DeathRecipient recipient, int flags) {
308 }
309
310 /**
311 * Local implementation is a no-op.
312 */
313 public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
314 return true;
315 }
316
317 protected void finalize() throws Throwable {
318 try {
319 destroy();
320 } finally {
321 super.finalize();
322 }
323 }
324
325 private native final void init();
326 private native final void destroy();
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700327
328 // Entry point from android_util_Binder.cpp's onTransact
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 private boolean execTransact(int code, int dataObj, int replyObj,
330 int flags) {
331 Parcel data = Parcel.obtain(dataObj);
332 Parcel reply = Parcel.obtain(replyObj);
333 // theoretically, we should call transact, which will call onTransact,
334 // but all that does is rewind it, and we just got these from an IPC,
335 // so we'll just call it directly.
336 boolean res;
337 try {
338 res = onTransact(code, data, reply, flags);
339 } catch (RemoteException e) {
Jeff Sharkey7f97e652011-12-14 18:07:54 -0800340 reply.setDataPosition(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 reply.writeException(e);
342 res = true;
343 } catch (RuntimeException e) {
Jeff Sharkey7f97e652011-12-14 18:07:54 -0800344 reply.setDataPosition(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 reply.writeException(e);
346 res = true;
Mattias Petersson19f22742010-11-05 08:25:38 +0100347 } catch (OutOfMemoryError e) {
348 RuntimeException re = new RuntimeException("Out of memory", e);
Jeff Sharkey7f97e652011-12-14 18:07:54 -0800349 reply.setDataPosition(0);
Mattias Petersson19f22742010-11-05 08:25:38 +0100350 reply.writeException(re);
351 res = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 }
353 reply.recycle();
354 data.recycle();
355 return res;
356 }
357}
358
359final class BinderProxy implements IBinder {
360 public native boolean pingBinder();
361 public native boolean isBinderAlive();
362
363 public IInterface queryLocalInterface(String descriptor) {
364 return null;
365 }
366
367 public native String getInterfaceDescriptor() throws RemoteException;
368 public native boolean transact(int code, Parcel data, Parcel reply,
369 int flags) throws RemoteException;
370 public native void linkToDeath(DeathRecipient recipient, int flags)
371 throws RemoteException;
372 public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
373
374 public void dump(FileDescriptor fd, String[] args) throws RemoteException {
375 Parcel data = Parcel.obtain();
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700376 Parcel reply = Parcel.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 data.writeFileDescriptor(fd);
378 data.writeStringArray(args);
379 try {
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700380 transact(DUMP_TRANSACTION, data, reply, 0);
381 reply.readException();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 } finally {
383 data.recycle();
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700384 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 }
386 }
387
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700388 public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
389 Parcel data = Parcel.obtain();
390 Parcel reply = Parcel.obtain();
391 data.writeFileDescriptor(fd);
392 data.writeStringArray(args);
393 try {
394 transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
395 reply.readException();
396 } finally {
397 data.recycle();
398 reply.recycle();
399 }
400 }
401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 BinderProxy() {
403 mSelf = new WeakReference(this);
404 }
405
406 @Override
407 protected void finalize() throws Throwable {
408 try {
409 destroy();
410 } finally {
411 super.finalize();
412 }
413 }
414
415 private native final void destroy();
416
417 private static final void sendDeathNotice(DeathRecipient recipient) {
Joe Onorato43a17652011-04-06 19:22:23 -0700418 if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 try {
420 recipient.binderDied();
421 }
422 catch (RuntimeException exc) {
423 Log.w("BinderNative", "Uncaught exception from death notification",
424 exc);
425 }
426 }
427
428 final private WeakReference mSelf;
429 private int mObject;
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800430 private int mOrgue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431}