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