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