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