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