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