Binder.java revision 5b88a2fd7b77880f6e09ae4a1de509bebe28bc3a
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;
20
21import java.io.FileDescriptor;
22import java.io.FileOutputStream;
23import java.io.IOException;
24import java.io.PrintWriter;
25import java.lang.ref.WeakReference;
26import 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 */
43public 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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
159    public static final native void joinThreadPool();
160
161    /**
162     * Returns true if the specified interface is a proxy.
163     * @hide
164     */
165    public static final boolean isProxy(IInterface iface) {
166        return iface.asBinder() != iface;
167    }
168
169    /**
170     * Default constructor initializes the object.
171     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
357    public void linkToDeath(DeathRecipient recipient, int flags) {
358    }
359
360    /**
361     * Local implementation is a no-op.
362     */
363    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
364        return true;
365    }
366
367    protected void finalize() throws Throwable {
368        try {
369            destroy();
370        } finally {
371            super.finalize();
372        }
373    }
374
375    private native final void init();
376    private native final void destroy();
377
378    // Entry point from android_util_Binder.cpp's onTransact
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
409final class BinderProxy implements IBinder {
410    public native boolean pingBinder();
411    public native boolean isBinderAlive();
412
413    public IInterface queryLocalInterface(String descriptor) {
414        return null;
415    }
416
417    public native String getInterfaceDescriptor() throws RemoteException;
418    public native boolean transact(int code, Parcel data, Parcel reply,
419            int flags) throws RemoteException;
420    public native void linkToDeath(DeathRecipient recipient, int flags)
421            throws RemoteException;
422    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
423
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
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
452    BinderProxy() {
453        mSelf = new WeakReference(this);
454    }
455
456    @Override
457    protected void finalize() throws Throwable {
458        try {
459            destroy();
460        } finally {
461            super.finalize();
462        }
463    }
464
465    private native final void destroy();
466
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