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/developing/tools/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 ID of the user 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 original ID of the user assigned to the process that sent you the current
77     * transaction that is being processed. This uid can be used with higher-level system services
78     * to determine its identity and check permissions. If the current thread is not currently
79     * executing an incoming transaction, then its own uid is returned.
80     * <p/>
81     * This value cannot be reset by calls to {@link #clearCallingIdentity()}.
82     * @hide
83     */
84    public static final int getOrigCallingUid() {
85        if (UserId.MU_ENABLED) {
86            return getOrigCallingUidNative();
87        } else {
88            return getCallingUid();
89        }
90    }
91
92    private static final native int getOrigCallingUidNative();
93
94    /**
95     * Utility function to return the user id of the calling process.
96     * @return userId of the calling process, extracted from the callingUid
97     * @hide
98     */
99    public static final int getOrigCallingUser() {
100        return UserId.getUserId(getOrigCallingUid());
101    }
102
103    /**
104     * Reset the identity of the incoming IPC on the current thread.  This can
105     * be useful if, while handling an incoming call, you will be calling
106     * on interfaces of other objects that may be local to your process and
107     * need to do permission checks on the calls coming into them (so they
108     * will check the permission of your own local process, and not whatever
109     * process originally called you).
110     *
111     * @return Returns an opaque token that can be used to restore the
112     * original calling identity by passing it to
113     * {@link #restoreCallingIdentity(long)}.
114     *
115     * @see #getCallingPid()
116     * @see #getCallingUid()
117     * @see #restoreCallingIdentity(long)
118     */
119    public static final native long clearCallingIdentity();
120
121    /**
122     * Restore the identity of the incoming IPC on the current thread
123     * back to a previously identity that was returned by {@link
124     * #clearCallingIdentity}.
125     *
126     * @param token The opaque token that was previously returned by
127     * {@link #clearCallingIdentity}.
128     *
129     * @see #clearCallingIdentity
130     */
131    public static final native void restoreCallingIdentity(long token);
132
133    /**
134     * Sets the native thread-local StrictMode policy mask.
135     *
136     * <p>The StrictMode settings are kept in two places: a Java-level
137     * threadlocal for libcore/Dalvik, and a native threadlocal (set
138     * here) for propagation via Binder calls.  This is a little
139     * unfortunate, but necessary to break otherwise more unfortunate
140     * dependencies either of Dalvik on Android, or Android
141     * native-only code on Dalvik.
142     *
143     * @see StrictMode
144     * @hide
145     */
146    public static final native void setThreadStrictModePolicy(int policyMask);
147
148    /**
149     * Gets the current native thread-local StrictMode policy mask.
150     *
151     * @see #setThreadStrictModePolicy
152     * @hide
153     */
154    public static final native int getThreadStrictModePolicy();
155
156    /**
157     * Flush any Binder commands pending in the current thread to the kernel
158     * driver.  This can be
159     * useful to call before performing an operation that may block for a long
160     * time, to ensure that any pending object references have been released
161     * in order to prevent the process from holding on to objects longer than
162     * it needs to.
163     */
164    public static final native void flushPendingCommands();
165
166    /**
167     * Add the calling thread to the IPC thread pool.  This function does
168     * not return until the current process is exiting.
169     */
170    public static final native void joinThreadPool();
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     * Default implementation is a stub that returns false.  You will want
238     * to override this to do the appropriate unmarshalling of transactions.
239     *
240     * <p>If you want to call this, call transact().
241     */
242    protected boolean onTransact(int code, Parcel data, Parcel reply,
243            int flags) throws RemoteException {
244        if (code == INTERFACE_TRANSACTION) {
245            reply.writeString(getInterfaceDescriptor());
246            return true;
247        } else if (code == DUMP_TRANSACTION) {
248            ParcelFileDescriptor fd = data.readFileDescriptor();
249            String[] args = data.readStringArray();
250            if (fd != null) {
251                try {
252                    dump(fd.getFileDescriptor(), args);
253                } finally {
254                    try {
255                        fd.close();
256                    } catch (IOException e) {
257                        // swallowed, not propagated back to the caller
258                    }
259                }
260            }
261            // Write the StrictMode header.
262            if (reply != null) {
263                reply.writeNoException();
264            } else {
265                StrictMode.clearGatheredViolations();
266            }
267            return true;
268        }
269        return false;
270    }
271
272    /**
273     * Implemented to call the more convenient version
274     * {@link #dump(FileDescriptor, PrintWriter, String[])}.
275     */
276    public void dump(FileDescriptor fd, String[] args) {
277        FileOutputStream fout = new FileOutputStream(fd);
278        PrintWriter pw = new PrintWriter(fout);
279        try {
280            dump(fd, pw, args);
281        } finally {
282            pw.flush();
283        }
284    }
285
286    /**
287     * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
288     * executes asynchronously.
289     */
290    public void dumpAsync(final FileDescriptor fd, final String[] args) {
291        final FileOutputStream fout = new FileOutputStream(fd);
292        final PrintWriter pw = new PrintWriter(fout);
293        Thread thr = new Thread("Binder.dumpAsync") {
294            public void run() {
295                try {
296                    dump(fd, pw, args);
297                } finally {
298                    pw.flush();
299                }
300            }
301        };
302        thr.start();
303    }
304
305    /**
306     * Print the object's state into the given stream.
307     *
308     * @param fd The raw file descriptor that the dump is being sent to.
309     * @param fout The file to which you should dump your state.  This will be
310     * closed for you after you return.
311     * @param args additional arguments to the dump request.
312     */
313    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
314    }
315
316    /**
317     * Default implementation rewinds the parcels and calls onTransact.  On
318     * the remote side, transact calls into the binder to do the IPC.
319     */
320    public final boolean transact(int code, Parcel data, Parcel reply,
321            int flags) throws RemoteException {
322        if (false) Log.v("Binder", "Transact: " + code + " to " + this);
323        if (data != null) {
324            data.setDataPosition(0);
325        }
326        boolean r = onTransact(code, data, reply, flags);
327        if (reply != null) {
328            reply.setDataPosition(0);
329        }
330        return r;
331    }
332
333    /**
334     * Local implementation is a no-op.
335     */
336    public void linkToDeath(DeathRecipient recipient, int flags) {
337    }
338
339    /**
340     * Local implementation is a no-op.
341     */
342    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
343        return true;
344    }
345
346    protected void finalize() throws Throwable {
347        try {
348            destroy();
349        } finally {
350            super.finalize();
351        }
352    }
353
354    private native final void init();
355    private native final void destroy();
356
357    // Entry point from android_util_Binder.cpp's onTransact
358    private boolean execTransact(int code, int dataObj, int replyObj,
359            int flags) {
360        Parcel data = Parcel.obtain(dataObj);
361        Parcel reply = Parcel.obtain(replyObj);
362        // theoretically, we should call transact, which will call onTransact,
363        // but all that does is rewind it, and we just got these from an IPC,
364        // so we'll just call it directly.
365        boolean res;
366        try {
367            res = onTransact(code, data, reply, flags);
368        } catch (RemoteException e) {
369            reply.setDataPosition(0);
370            reply.writeException(e);
371            res = true;
372        } catch (RuntimeException e) {
373            reply.setDataPosition(0);
374            reply.writeException(e);
375            res = true;
376        } catch (OutOfMemoryError e) {
377            RuntimeException re = new RuntimeException("Out of memory", e);
378            reply.setDataPosition(0);
379            reply.writeException(re);
380            res = true;
381        }
382        reply.recycle();
383        data.recycle();
384        return res;
385    }
386}
387
388final class BinderProxy implements IBinder {
389    public native boolean pingBinder();
390    public native boolean isBinderAlive();
391
392    public IInterface queryLocalInterface(String descriptor) {
393        return null;
394    }
395
396    public native String getInterfaceDescriptor() throws RemoteException;
397    public native boolean transact(int code, Parcel data, Parcel reply,
398            int flags) throws RemoteException;
399    public native void linkToDeath(DeathRecipient recipient, int flags)
400            throws RemoteException;
401    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
402
403    public void dump(FileDescriptor fd, String[] args) throws RemoteException {
404        Parcel data = Parcel.obtain();
405        Parcel reply = Parcel.obtain();
406        data.writeFileDescriptor(fd);
407        data.writeStringArray(args);
408        try {
409            transact(DUMP_TRANSACTION, data, reply, 0);
410            reply.readException();
411        } finally {
412            data.recycle();
413            reply.recycle();
414        }
415    }
416
417    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
418        Parcel data = Parcel.obtain();
419        Parcel reply = Parcel.obtain();
420        data.writeFileDescriptor(fd);
421        data.writeStringArray(args);
422        try {
423            transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
424            reply.readException();
425        } finally {
426            data.recycle();
427            reply.recycle();
428        }
429    }
430
431    BinderProxy() {
432        mSelf = new WeakReference(this);
433    }
434
435    @Override
436    protected void finalize() throws Throwable {
437        try {
438            destroy();
439        } finally {
440            super.finalize();
441        }
442    }
443
444    private native final void destroy();
445
446    private static final void sendDeathNotice(DeathRecipient recipient) {
447        if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
448        try {
449            recipient.binderDied();
450        }
451        catch (RuntimeException exc) {
452            Log.w("BinderNative", "Uncaught exception from death notification",
453                    exc);
454        }
455    }
456
457    final private WeakReference mSelf;
458    private int mObject;
459    private int mOrgue;
460}
461