• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.os;
18 
19 import android.util.Log;
20 
21 import java.io.FileDescriptor;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.PrintWriter;
25 import java.lang.ref.WeakReference;
26 import 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/components/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  */
43 public 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     /**
53      * Control whether dump() calls are allowed.
54      */
55     private static String sDumpDisabled = null;
56 
57     /* mObject is used by native code, do not remove or rename */
58     private int mObject;
59     private IInterface mOwner;
60     private String mDescriptor;
61 
62     /**
63      * Return the ID of the process that sent you the current transaction
64      * that is being processed.  This pid can be used with higher-level
65      * system services to determine its identity and check permissions.
66      * If the current thread is not currently executing an incoming transaction,
67      * then its own pid is returned.
68      */
getCallingPid()69     public static final native int getCallingPid();
70 
71     /**
72      * Return the Linux uid assigned to the process that sent you the
73      * current transaction that is being processed.  This uid can be used with
74      * higher-level system services to determine its identity and check
75      * permissions.  If the current thread is not currently executing an
76      * incoming transaction, then its own uid is returned.
77      */
getCallingUid()78     public static final native int getCallingUid();
79 
80     /**
81      * Return the UserHandle assigned to the process that sent you the
82      * current transaction that is being processed.  This is the user
83      * of the caller.  It is distinct from {@link #getCallingUid()} in that a
84      * particular user will have multiple distinct apps running under it each
85      * with their own uid.  If the current thread is not currently executing an
86      * incoming transaction, then its own UserHandle is returned.
87      */
getCallingUserHandle()88     public static final UserHandle getCallingUserHandle() {
89         return new UserHandle(UserHandle.getUserId(getCallingUid()));
90     }
91 
92     /**
93      * Reset the identity of the incoming IPC on the current thread.  This can
94      * be useful if, while handling an incoming call, you will be calling
95      * on interfaces of other objects that may be local to your process and
96      * need to do permission checks on the calls coming into them (so they
97      * will check the permission of your own local process, and not whatever
98      * process originally called you).
99      *
100      * @return Returns an opaque token that can be used to restore the
101      * original calling identity by passing it to
102      * {@link #restoreCallingIdentity(long)}.
103      *
104      * @see #getCallingPid()
105      * @see #getCallingUid()
106      * @see #restoreCallingIdentity(long)
107      */
clearCallingIdentity()108     public static final native long clearCallingIdentity();
109 
110     /**
111      * Restore the identity of the incoming IPC on the current thread
112      * back to a previously identity that was returned by {@link
113      * #clearCallingIdentity}.
114      *
115      * @param token The opaque token that was previously returned by
116      * {@link #clearCallingIdentity}.
117      *
118      * @see #clearCallingIdentity
119      */
restoreCallingIdentity(long token)120     public static final native void restoreCallingIdentity(long token);
121 
122     /**
123      * Sets the native thread-local StrictMode policy mask.
124      *
125      * <p>The StrictMode settings are kept in two places: a Java-level
126      * threadlocal for libcore/Dalvik, and a native threadlocal (set
127      * here) for propagation via Binder calls.  This is a little
128      * unfortunate, but necessary to break otherwise more unfortunate
129      * dependencies either of Dalvik on Android, or Android
130      * native-only code on Dalvik.
131      *
132      * @see StrictMode
133      * @hide
134      */
setThreadStrictModePolicy(int policyMask)135     public static final native void setThreadStrictModePolicy(int policyMask);
136 
137     /**
138      * Gets the current native thread-local StrictMode policy mask.
139      *
140      * @see #setThreadStrictModePolicy
141      * @hide
142      */
getThreadStrictModePolicy()143     public static final native int getThreadStrictModePolicy();
144 
145     /**
146      * Flush any Binder commands pending in the current thread to the kernel
147      * driver.  This can be
148      * useful to call before performing an operation that may block for a long
149      * time, to ensure that any pending object references have been released
150      * in order to prevent the process from holding on to objects longer than
151      * it needs to.
152      */
flushPendingCommands()153     public static final native void flushPendingCommands();
154 
155     /**
156      * Add the calling thread to the IPC thread pool.  This function does
157      * not return until the current process is exiting.
158      */
joinThreadPool()159     public static final native void joinThreadPool();
160 
161     /**
162      * Returns true if the specified interface is a proxy.
163      * @hide
164      */
isProxy(IInterface iface)165     public static final boolean isProxy(IInterface iface) {
166         return iface.asBinder() != iface;
167     }
168 
169     /**
170      * Default constructor initializes the object.
171      */
Binder()172     public Binder() {
173         init();
174 
175         if (FIND_POTENTIAL_LEAKS) {
176             final Class<? extends Binder> klass = getClass();
177             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
178                     (klass.getModifiers() & Modifier.STATIC) == 0) {
179                 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
180                     klass.getCanonicalName());
181             }
182         }
183     }
184 
185     /**
186      * Convenience method for associating a specific interface with the Binder.
187      * After calling, queryLocalInterface() will be implemented for you
188      * to return the given owner IInterface when the corresponding
189      * descriptor is requested.
190      */
attachInterface(IInterface owner, String descriptor)191     public void attachInterface(IInterface owner, String descriptor) {
192         mOwner = owner;
193         mDescriptor = descriptor;
194     }
195 
196     /**
197      * Default implementation returns an empty interface name.
198      */
getInterfaceDescriptor()199     public String getInterfaceDescriptor() {
200         return mDescriptor;
201     }
202 
203     /**
204      * Default implementation always returns true -- if you got here,
205      * the object is alive.
206      */
pingBinder()207     public boolean pingBinder() {
208         return true;
209     }
210 
211     /**
212      * {@inheritDoc}
213      *
214      * Note that if you're calling on a local binder, this always returns true
215      * because your process is alive if you're calling it.
216      */
isBinderAlive()217     public boolean isBinderAlive() {
218         return true;
219     }
220 
221     /**
222      * Use information supplied to attachInterface() to return the
223      * associated IInterface if it matches the requested
224      * descriptor.
225      */
queryLocalInterface(String descriptor)226     public IInterface queryLocalInterface(String descriptor) {
227         if (mDescriptor.equals(descriptor)) {
228             return mOwner;
229         }
230         return null;
231     }
232 
233     /**
234      * Control disabling of dump calls in this process.  This is used by the system
235      * process watchdog to disable incoming dump calls while it has detecting the system
236      * is hung and is reporting that back to the activity controller.  This is to
237      * prevent the controller from getting hung up on bug reports at this point.
238      * @hide
239      *
240      * @param msg The message to show instead of the dump; if null, dumps are
241      * re-enabled.
242      */
setDumpDisabled(String msg)243     public static void setDumpDisabled(String msg) {
244         synchronized (Binder.class) {
245             sDumpDisabled = msg;
246         }
247     }
248 
249     /**
250      * Default implementation is a stub that returns false.  You will want
251      * to override this to do the appropriate unmarshalling of transactions.
252      *
253      * <p>If you want to call this, call transact().
254      */
onTransact(int code, Parcel data, Parcel reply, int flags)255     protected boolean onTransact(int code, Parcel data, Parcel reply,
256             int flags) throws RemoteException {
257         if (code == INTERFACE_TRANSACTION) {
258             reply.writeString(getInterfaceDescriptor());
259             return true;
260         } else if (code == DUMP_TRANSACTION) {
261             ParcelFileDescriptor fd = data.readFileDescriptor();
262             String[] args = data.readStringArray();
263             if (fd != null) {
264                 try {
265                     dump(fd.getFileDescriptor(), args);
266                 } finally {
267                     try {
268                         fd.close();
269                     } catch (IOException e) {
270                         // swallowed, not propagated back to the caller
271                     }
272                 }
273             }
274             // Write the StrictMode header.
275             if (reply != null) {
276                 reply.writeNoException();
277             } else {
278                 StrictMode.clearGatheredViolations();
279             }
280             return true;
281         }
282         return false;
283     }
284 
285     /**
286      * Implemented to call the more convenient version
287      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
288      */
dump(FileDescriptor fd, String[] args)289     public void dump(FileDescriptor fd, String[] args) {
290         FileOutputStream fout = new FileOutputStream(fd);
291         PrintWriter pw = new PrintWriter(fout);
292         try {
293             final String disabled;
294             synchronized (Binder.class) {
295                 disabled = sDumpDisabled;
296             }
297             if (disabled == null) {
298                 dump(fd, pw, args);
299             } else {
300                 pw.println(sDumpDisabled);
301             }
302         } finally {
303             pw.flush();
304         }
305     }
306 
307     /**
308      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
309      * executes asynchronously.
310      */
dumpAsync(final FileDescriptor fd, final String[] args)311     public void dumpAsync(final FileDescriptor fd, final String[] args) {
312         final FileOutputStream fout = new FileOutputStream(fd);
313         final PrintWriter pw = new PrintWriter(fout);
314         Thread thr = new Thread("Binder.dumpAsync") {
315             public void run() {
316                 try {
317                     dump(fd, pw, args);
318                 } finally {
319                     pw.flush();
320                 }
321             }
322         };
323         thr.start();
324     }
325 
326     /**
327      * Print the object's state into the given stream.
328      *
329      * @param fd The raw file descriptor that the dump is being sent to.
330      * @param fout The file to which you should dump your state.  This will be
331      * closed for you after you return.
332      * @param args additional arguments to the dump request.
333      */
dump(FileDescriptor fd, PrintWriter fout, String[] args)334     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
335     }
336 
337     /**
338      * Default implementation rewinds the parcels and calls onTransact.  On
339      * the remote side, transact calls into the binder to do the IPC.
340      */
transact(int code, Parcel data, Parcel reply, int flags)341     public final boolean transact(int code, Parcel data, Parcel reply,
342             int flags) throws RemoteException {
343         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
344         if (data != null) {
345             data.setDataPosition(0);
346         }
347         boolean r = onTransact(code, data, reply, flags);
348         if (reply != null) {
349             reply.setDataPosition(0);
350         }
351         return r;
352     }
353 
354     /**
355      * Local implementation is a no-op.
356      */
linkToDeath(DeathRecipient recipient, int flags)357     public void linkToDeath(DeathRecipient recipient, int flags) {
358     }
359 
360     /**
361      * Local implementation is a no-op.
362      */
unlinkToDeath(DeathRecipient recipient, int flags)363     public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
364         return true;
365     }
366 
finalize()367     protected void finalize() throws Throwable {
368         try {
369             destroy();
370         } finally {
371             super.finalize();
372         }
373     }
374 
init()375     private native final void init();
destroy()376     private native final void destroy();
377 
378     // Entry point from android_util_Binder.cpp's onTransact
execTransact(int code, int dataObj, int replyObj, int flags)379     private boolean execTransact(int code, int dataObj, int replyObj,
380             int flags) {
381         Parcel data = Parcel.obtain(dataObj);
382         Parcel reply = Parcel.obtain(replyObj);
383         // theoretically, we should call transact, which will call onTransact,
384         // but all that does is rewind it, and we just got these from an IPC,
385         // so we'll just call it directly.
386         boolean res;
387         try {
388             res = onTransact(code, data, reply, flags);
389         } catch (RemoteException e) {
390             reply.setDataPosition(0);
391             reply.writeException(e);
392             res = true;
393         } catch (RuntimeException e) {
394             reply.setDataPosition(0);
395             reply.writeException(e);
396             res = true;
397         } catch (OutOfMemoryError e) {
398             RuntimeException re = new RuntimeException("Out of memory", e);
399             reply.setDataPosition(0);
400             reply.writeException(re);
401             res = true;
402         }
403         reply.recycle();
404         data.recycle();
405         return res;
406     }
407 }
408 
409 final class BinderProxy implements IBinder {
pingBinder()410     public native boolean pingBinder();
isBinderAlive()411     public native boolean isBinderAlive();
412 
queryLocalInterface(String descriptor)413     public IInterface queryLocalInterface(String descriptor) {
414         return null;
415     }
416 
getInterfaceDescriptor()417     public native String getInterfaceDescriptor() throws RemoteException;
transact(int code, Parcel data, Parcel reply, int flags)418     public native boolean transact(int code, Parcel data, Parcel reply,
419             int flags) throws RemoteException;
linkToDeath(DeathRecipient recipient, int flags)420     public native void linkToDeath(DeathRecipient recipient, int flags)
421             throws RemoteException;
unlinkToDeath(DeathRecipient recipient, int flags)422     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
423 
dump(FileDescriptor fd, String[] args)424     public void dump(FileDescriptor fd, String[] args) throws RemoteException {
425         Parcel data = Parcel.obtain();
426         Parcel reply = Parcel.obtain();
427         data.writeFileDescriptor(fd);
428         data.writeStringArray(args);
429         try {
430             transact(DUMP_TRANSACTION, data, reply, 0);
431             reply.readException();
432         } finally {
433             data.recycle();
434             reply.recycle();
435         }
436     }
437 
dumpAsync(FileDescriptor fd, String[] args)438     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
439         Parcel data = Parcel.obtain();
440         Parcel reply = Parcel.obtain();
441         data.writeFileDescriptor(fd);
442         data.writeStringArray(args);
443         try {
444             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
445             reply.readException();
446         } finally {
447             data.recycle();
448             reply.recycle();
449         }
450     }
451 
BinderProxy()452     BinderProxy() {
453         mSelf = new WeakReference(this);
454     }
455 
456     @Override
finalize()457     protected void finalize() throws Throwable {
458         try {
459             destroy();
460         } finally {
461             super.finalize();
462         }
463     }
464 
destroy()465     private native final void destroy();
466 
sendDeathNotice(DeathRecipient recipient)467     private static final void sendDeathNotice(DeathRecipient recipient) {
468         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
469         try {
470             recipient.binderDied();
471         }
472         catch (RuntimeException exc) {
473             Log.w("BinderNative", "Uncaught exception from death notification",
474                     exc);
475         }
476     }
477 
478     final private WeakReference mSelf;
479     private int mObject;
480     private int mOrgue;
481 }
482