Binder.java revision 1951ce86c21445ac191e4d2d95233f4f5c096b56
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    /* 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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
154    public static final native void joinThreadPool();
155
156    /**
157     * Returns true if the specified interface is a proxy.
158     * @hide
159     */
160    public static final boolean isProxy(IInterface iface) {
161        return iface.asBinder() != iface;
162    }
163
164    /**
165     * Default constructor initializes the object.
166     */
167    public Binder() {
168        init();
169
170        if (FIND_POTENTIAL_LEAKS) {
171            final Class<? extends Binder> klass = getClass();
172            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
173                    (klass.getModifiers() & Modifier.STATIC) == 0) {
174                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
175                    klass.getCanonicalName());
176            }
177        }
178    }
179
180    /**
181     * Convenience method for associating a specific interface with the Binder.
182     * After calling, queryLocalInterface() will be implemented for you
183     * to return the given owner IInterface when the corresponding
184     * descriptor is requested.
185     */
186    public void attachInterface(IInterface owner, String descriptor) {
187        mOwner = owner;
188        mDescriptor = descriptor;
189    }
190
191    /**
192     * Default implementation returns an empty interface name.
193     */
194    public String getInterfaceDescriptor() {
195        return mDescriptor;
196    }
197
198    /**
199     * Default implementation always returns true -- if you got here,
200     * the object is alive.
201     */
202    public boolean pingBinder() {
203        return true;
204    }
205
206    /**
207     * {@inheritDoc}
208     *
209     * Note that if you're calling on a local binder, this always returns true
210     * because your process is alive if you're calling it.
211     */
212    public boolean isBinderAlive() {
213        return true;
214    }
215
216    /**
217     * Use information supplied to attachInterface() to return the
218     * associated IInterface if it matches the requested
219     * descriptor.
220     */
221    public IInterface queryLocalInterface(String descriptor) {
222        if (mDescriptor.equals(descriptor)) {
223            return mOwner;
224        }
225        return null;
226    }
227
228    /**
229     * Default implementation is a stub that returns false.  You will want
230     * to override this to do the appropriate unmarshalling of transactions.
231     *
232     * <p>If you want to call this, call transact().
233     */
234    protected boolean onTransact(int code, Parcel data, Parcel reply,
235            int flags) throws RemoteException {
236        if (code == INTERFACE_TRANSACTION) {
237            reply.writeString(getInterfaceDescriptor());
238            return true;
239        } else if (code == DUMP_TRANSACTION) {
240            ParcelFileDescriptor fd = data.readFileDescriptor();
241            String[] args = data.readStringArray();
242            if (fd != null) {
243                try {
244                    dump(fd.getFileDescriptor(), args);
245                } finally {
246                    try {
247                        fd.close();
248                    } catch (IOException e) {
249                        // swallowed, not propagated back to the caller
250                    }
251                }
252            }
253            // Write the StrictMode header.
254            if (reply != null) {
255                reply.writeNoException();
256            } else {
257                StrictMode.clearGatheredViolations();
258            }
259            return true;
260        }
261        return false;
262    }
263
264    /**
265     * Implemented to call the more convenient version
266     * {@link #dump(FileDescriptor, PrintWriter, String[])}.
267     */
268    public void dump(FileDescriptor fd, String[] args) {
269        FileOutputStream fout = new FileOutputStream(fd);
270        PrintWriter pw = new PrintWriter(fout);
271        try {
272            dump(fd, pw, args);
273        } finally {
274            pw.flush();
275        }
276    }
277
278    /**
279     * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
280     * executes asynchronously.
281     */
282    public void dumpAsync(final FileDescriptor fd, final String[] args) {
283        final FileOutputStream fout = new FileOutputStream(fd);
284        final PrintWriter pw = new PrintWriter(fout);
285        Thread thr = new Thread("Binder.dumpAsync") {
286            public void run() {
287                try {
288                    dump(fd, pw, args);
289                } finally {
290                    pw.flush();
291                }
292            }
293        };
294        thr.start();
295    }
296
297    /**
298     * Print the object's state into the given stream.
299     *
300     * @param fd The raw file descriptor that the dump is being sent to.
301     * @param fout The file to which you should dump your state.  This will be
302     * closed for you after you return.
303     * @param args additional arguments to the dump request.
304     */
305    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
306    }
307
308    /**
309     * Default implementation rewinds the parcels and calls onTransact.  On
310     * the remote side, transact calls into the binder to do the IPC.
311     */
312    public final boolean transact(int code, Parcel data, Parcel reply,
313            int flags) throws RemoteException {
314        if (false) Log.v("Binder", "Transact: " + code + " to " + this);
315        if (data != null) {
316            data.setDataPosition(0);
317        }
318        boolean r = onTransact(code, data, reply, flags);
319        if (reply != null) {
320            reply.setDataPosition(0);
321        }
322        return r;
323    }
324
325    /**
326     * Local implementation is a no-op.
327     */
328    public void linkToDeath(DeathRecipient recipient, int flags) {
329    }
330
331    /**
332     * Local implementation is a no-op.
333     */
334    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
335        return true;
336    }
337
338    protected void finalize() throws Throwable {
339        try {
340            destroy();
341        } finally {
342            super.finalize();
343        }
344    }
345
346    private native final void init();
347    private native final void destroy();
348
349    // Entry point from android_util_Binder.cpp's onTransact
350    private boolean execTransact(int code, int dataObj, int replyObj,
351            int flags) {
352        Parcel data = Parcel.obtain(dataObj);
353        Parcel reply = Parcel.obtain(replyObj);
354        // theoretically, we should call transact, which will call onTransact,
355        // but all that does is rewind it, and we just got these from an IPC,
356        // so we'll just call it directly.
357        boolean res;
358        try {
359            res = onTransact(code, data, reply, flags);
360        } catch (RemoteException e) {
361            reply.setDataPosition(0);
362            reply.writeException(e);
363            res = true;
364        } catch (RuntimeException e) {
365            reply.setDataPosition(0);
366            reply.writeException(e);
367            res = true;
368        } catch (OutOfMemoryError e) {
369            RuntimeException re = new RuntimeException("Out of memory", e);
370            reply.setDataPosition(0);
371            reply.writeException(re);
372            res = true;
373        }
374        reply.recycle();
375        data.recycle();
376        return res;
377    }
378}
379
380final class BinderProxy implements IBinder {
381    public native boolean pingBinder();
382    public native boolean isBinderAlive();
383
384    public IInterface queryLocalInterface(String descriptor) {
385        return null;
386    }
387
388    public native String getInterfaceDescriptor() throws RemoteException;
389    public native boolean transact(int code, Parcel data, Parcel reply,
390            int flags) throws RemoteException;
391    public native void linkToDeath(DeathRecipient recipient, int flags)
392            throws RemoteException;
393    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
394
395    public void dump(FileDescriptor fd, String[] args) throws RemoteException {
396        Parcel data = Parcel.obtain();
397        Parcel reply = Parcel.obtain();
398        data.writeFileDescriptor(fd);
399        data.writeStringArray(args);
400        try {
401            transact(DUMP_TRANSACTION, data, reply, 0);
402            reply.readException();
403        } finally {
404            data.recycle();
405            reply.recycle();
406        }
407    }
408
409    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
410        Parcel data = Parcel.obtain();
411        Parcel reply = Parcel.obtain();
412        data.writeFileDescriptor(fd);
413        data.writeStringArray(args);
414        try {
415            transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
416            reply.readException();
417        } finally {
418            data.recycle();
419            reply.recycle();
420        }
421    }
422
423    BinderProxy() {
424        mSelf = new WeakReference(this);
425    }
426
427    @Override
428    protected void finalize() throws Throwable {
429        try {
430            destroy();
431        } finally {
432            super.finalize();
433        }
434    }
435
436    private native final void destroy();
437
438    private static final void sendDeathNotice(DeathRecipient recipient) {
439        if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
440        try {
441            recipient.binderDied();
442        }
443        catch (RuntimeException exc) {
444            Log.w("BinderNative", "Uncaught exception from death notification",
445                    exc);
446        }
447    }
448
449    final private WeakReference mSelf;
450    private int mObject;
451    private int mOrgue;
452}
453