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