[go: nahoru, domu]

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;
22import libcore.io.IoUtils;
23
24import java.io.FileDescriptor;
25import java.io.FileOutputStream;
26import java.io.IOException;
27import java.io.PrintWriter;
28import java.lang.ref.WeakReference;
29import java.lang.reflect.Modifier;
30
31/**
32 * Base class for a remotable object, the core part of a lightweight
33 * remote procedure call mechanism defined by {@link IBinder}.
34 * This class is an implementation of IBinder that provides
35 * standard local implementation of such an object.
36 *
37 * <p>Most developers will not implement this class directly, instead using the
38 * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
39 * interface, having it generate the appropriate Binder subclass.  You can,
40 * however, derive directly from Binder to implement your own custom RPC
41 * protocol or simply instantiate a raw Binder object directly to use as a
42 * token that can be shared across processes.
43 *
44 * <p>This class is just a basic IPC primitive; it has no impact on an application's
45 * lifecycle, and is valid only as long as the process that created it continues to run.
46 * To use this correctly, you must be doing so within the context of a top-level
47 * application component (a {@link android.app.Service}, {@link android.app.Activity},
48 * or {@link android.content.ContentProvider}) that lets the system know your process
49 * should remain running.</p>
50 *
51 * <p>You must keep in mind the situations in which your process
52 * could go away, and thus require that you later re-create a new Binder and re-attach
53 * it when the process starts again.  For example, if you are using this within an
54 * {@link android.app.Activity}, your activity's process may be killed any time the
55 * activity is not started; if the activity is later re-created you will need to
56 * create a new Binder and hand it back to the correct place again; you need to be
57 * aware that your process may be started for another reason (for example to receive
58 * a broadcast) that will not involve re-creating the activity and thus run its code
59 * to create a new Binder.</p>
60 *
61 * @see IBinder
62 */
63public class Binder implements IBinder {
64    /*
65     * Set this flag to true to detect anonymous, local or member classes
66     * that extend this Binder class and that are not static. These kind
67     * of classes can potentially create leaks.
68     */
69    private static final boolean FIND_POTENTIAL_LEAKS = false;
70    private static final boolean CHECK_PARCEL_SIZE = false;
71    static final String TAG = "Binder";
72
73    /** @hide */
74    public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE
75
76    /**
77     * Control whether dump() calls are allowed.
78     */
79    private static String sDumpDisabled = null;
80
81    /**
82     * Global transaction tracker instance for this process.
83     */
84    private static TransactionTracker sTransactionTracker = null;
85
86    // Transaction tracking code.
87
88    /**
89     * Flag indicating whether we should be tracing transact calls.
90     *
91     */
92    private static boolean sTracingEnabled = false;
93
94    /**
95     * Enable Binder IPC tracing.
96     *
97     * @hide
98     */
99    public static void  enableTracing() {
100        sTracingEnabled = true;
101    };
102
103    /**
104     * Disable Binder IPC tracing.
105     *
106     * @hide
107     */
108    public static void  disableTracing() {
109        sTracingEnabled = false;
110    }
111
112    /**
113     * Check if binder transaction tracing is enabled.
114     *
115     * @hide
116     */
117    public static boolean isTracingEnabled() {
118        return sTracingEnabled;
119    }
120
121    /**
122     * Get the binder transaction tracker for this process.
123     *
124     * @hide
125     */
126    public synchronized static TransactionTracker getTransactionTracker() {
127        if (sTransactionTracker == null)
128            sTransactionTracker = new TransactionTracker();
129        return sTransactionTracker;
130    }
131
132    /* mObject is used by native code, do not remove or rename */
133    private long mObject;
134    private IInterface mOwner;
135    private String mDescriptor;
136
137    /**
138     * Return the ID of the process that sent you the current transaction
139     * that is being processed.  This pid can be used with higher-level
140     * system services to determine its identity and check permissions.
141     * If the current thread is not currently executing an incoming transaction,
142     * then its own pid is returned.
143     */
144    public static final native int getCallingPid();
145
146    /**
147     * Return the Linux uid assigned to the process that sent you the
148     * current transaction that is being processed.  This uid can be used with
149     * higher-level system services to determine its identity and check
150     * permissions.  If the current thread is not currently executing an
151     * incoming transaction, then its own uid is returned.
152     */
153    public static final native int getCallingUid();
154
155    /**
156     * Return the UserHandle assigned to the process that sent you the
157     * current transaction that is being processed.  This is the user
158     * of the caller.  It is distinct from {@link #getCallingUid()} in that a
159     * particular user will have multiple distinct apps running under it each
160     * with their own uid.  If the current thread is not currently executing an
161     * incoming transaction, then its own UserHandle is returned.
162     */
163    public static final UserHandle getCallingUserHandle() {
164        return UserHandle.of(UserHandle.getUserId(getCallingUid()));
165    }
166
167    /**
168     * Reset the identity of the incoming IPC on the current thread.  This can
169     * be useful if, while handling an incoming call, you will be calling
170     * on interfaces of other objects that may be local to your process and
171     * need to do permission checks on the calls coming into them (so they
172     * will check the permission of your own local process, and not whatever
173     * process originally called you).
174     *
175     * @return Returns an opaque token that can be used to restore the
176     * original calling identity by passing it to
177     * {@link #restoreCallingIdentity(long)}.
178     *
179     * @see #getCallingPid()
180     * @see #getCallingUid()
181     * @see #restoreCallingIdentity(long)
182     */
183    public static final native long clearCallingIdentity();
184
185    /**
186     * Restore the identity of the incoming IPC on the current thread
187     * back to a previously identity that was returned by {@link
188     * #clearCallingIdentity}.
189     *
190     * @param token The opaque token that was previously returned by
191     * {@link #clearCallingIdentity}.
192     *
193     * @see #clearCallingIdentity
194     */
195    public static final native void restoreCallingIdentity(long token);
196
197    /**
198     * Sets the native thread-local StrictMode policy mask.
199     *
200     * <p>The StrictMode settings are kept in two places: a Java-level
201     * threadlocal for libcore/Dalvik, and a native threadlocal (set
202     * here) for propagation via Binder calls.  This is a little
203     * unfortunate, but necessary to break otherwise more unfortunate
204     * dependencies either of Dalvik on Android, or Android
205     * native-only code on Dalvik.
206     *
207     * @see StrictMode
208     * @hide
209     */
210    public static final native void setThreadStrictModePolicy(int policyMask);
211
212    /**
213     * Gets the current native thread-local StrictMode policy mask.
214     *
215     * @see #setThreadStrictModePolicy
216     * @hide
217     */
218    public static final native int getThreadStrictModePolicy();
219
220    /**
221     * Flush any Binder commands pending in the current thread to the kernel
222     * driver.  This can be
223     * useful to call before performing an operation that may block for a long
224     * time, to ensure that any pending object references have been released
225     * in order to prevent the process from holding on to objects longer than
226     * it needs to.
227     */
228    public static final native void flushPendingCommands();
229
230    /**
231     * Add the calling thread to the IPC thread pool.  This function does
232     * not return until the current process is exiting.
233     */
234    public static final native void joinThreadPool();
235
236    /**
237     * Returns true if the specified interface is a proxy.
238     * @hide
239     */
240    public static final boolean isProxy(IInterface iface) {
241        return iface.asBinder() != iface;
242    }
243
244    /**
245     * Call blocks until the number of executing binder threads is less
246     * than the maximum number of binder threads allowed for this process.
247     * @hide
248     */
249    public static final native void blockUntilThreadAvailable();
250
251    /**
252     * Default constructor initializes the object.
253     */
254    public Binder() {
255        init();
256
257        if (FIND_POTENTIAL_LEAKS) {
258            final Class<? extends Binder> klass = getClass();
259            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
260                    (klass.getModifiers() & Modifier.STATIC) == 0) {
261                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
262                    klass.getCanonicalName());
263            }
264        }
265    }
266
267    /**
268     * Convenience method for associating a specific interface with the Binder.
269     * After calling, queryLocalInterface() will be implemented for you
270     * to return the given owner IInterface when the corresponding
271     * descriptor is requested.
272     */
273    public void attachInterface(IInterface owner, String descriptor) {
274        mOwner = owner;
275        mDescriptor = descriptor;
276    }
277
278    /**
279     * Default implementation returns an empty interface name.
280     */
281    public String getInterfaceDescriptor() {
282        return mDescriptor;
283    }
284
285    /**
286     * Default implementation always returns true -- if you got here,
287     * the object is alive.
288     */
289    public boolean pingBinder() {
290        return true;
291    }
292
293    /**
294     * {@inheritDoc}
295     *
296     * Note that if you're calling on a local binder, this always returns true
297     * because your process is alive if you're calling it.
298     */
299    public boolean isBinderAlive() {
300        return true;
301    }
302
303    /**
304     * Use information supplied to attachInterface() to return the
305     * associated IInterface if it matches the requested
306     * descriptor.
307     */
308    public IInterface queryLocalInterface(String descriptor) {
309        if (mDescriptor.equals(descriptor)) {
310            return mOwner;
311        }
312        return null;
313    }
314
315    /**
316     * Control disabling of dump calls in this process.  This is used by the system
317     * process watchdog to disable incoming dump calls while it has detecting the system
318     * is hung and is reporting that back to the activity controller.  This is to
319     * prevent the controller from getting hung up on bug reports at this point.
320     * @hide
321     *
322     * @param msg The message to show instead of the dump; if null, dumps are
323     * re-enabled.
324     */
325    public static void setDumpDisabled(String msg) {
326        synchronized (Binder.class) {
327            sDumpDisabled = msg;
328        }
329    }
330
331    /**
332     * Default implementation is a stub that returns false.  You will want
333     * to override this to do the appropriate unmarshalling of transactions.
334     *
335     * <p>If you want to call this, call transact().
336     */
337    protected boolean onTransact(int code, Parcel data, Parcel reply,
338            int flags) throws RemoteException {
339        if (code == INTERFACE_TRANSACTION) {
340            reply.writeString(getInterfaceDescriptor());
341            return true;
342        } else if (code == DUMP_TRANSACTION) {
343            ParcelFileDescriptor fd = data.readFileDescriptor();
344            String[] args = data.readStringArray();
345            if (fd != null) {
346                try {
347                    dump(fd.getFileDescriptor(), args);
348                } finally {
349                    IoUtils.closeQuietly(fd);
350                }
351            }
352            // Write the StrictMode header.
353            if (reply != null) {
354                reply.writeNoException();
355            } else {
356                StrictMode.clearGatheredViolations();
357            }
358            return true;
359        } else if (code == SHELL_COMMAND_TRANSACTION) {
360            ParcelFileDescriptor in = data.readFileDescriptor();
361            ParcelFileDescriptor out = data.readFileDescriptor();
362            ParcelFileDescriptor err = data.readFileDescriptor();
363            String[] args = data.readStringArray();
364            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
365            try {
366                if (out != null) {
367                    shellCommand(in != null ? in.getFileDescriptor() : null,
368                            out.getFileDescriptor(),
369                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
370                            args, resultReceiver);
371                }
372            } finally {
373                IoUtils.closeQuietly(in);
374                IoUtils.closeQuietly(out);
375                IoUtils.closeQuietly(err);
376                // Write the StrictMode header.
377                if (reply != null) {
378                    reply.writeNoException();
379                } else {
380                    StrictMode.clearGatheredViolations();
381                }
382            }
383            return true;
384        }
385        return false;
386    }
387
388    /**
389     * Implemented to call the more convenient version
390     * {@link #dump(FileDescriptor, PrintWriter, String[])}.
391     */
392    public void dump(FileDescriptor fd, String[] args) {
393        FileOutputStream fout = new FileOutputStream(fd);
394        PrintWriter pw = new FastPrintWriter(fout);
395        try {
396            doDump(fd, pw, args);
397        } finally {
398            pw.flush();
399        }
400    }
401
402    void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
403        final String disabled;
404        synchronized (Binder.class) {
405            disabled = sDumpDisabled;
406        }
407        if (disabled == null) {
408            try {
409                dump(fd, pw, args);
410            } catch (SecurityException e) {
411                pw.println("Security exception: " + e.getMessage());
412                throw e;
413            } catch (Throwable e) {
414                // Unlike usual calls, in this case if an exception gets thrown
415                // back to us we want to print it back in to the dump data, since
416                // that is where the caller expects all interesting information to
417                // go.
418                pw.println();
419                pw.println("Exception occurred while dumping:");
420                e.printStackTrace(pw);
421            }
422        } else {
423            pw.println(sDumpDisabled);
424        }
425    }
426
427    /**
428     * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
429     * executes asynchronously.
430     */
431    public void dumpAsync(final FileDescriptor fd, final String[] args) {
432        final FileOutputStream fout = new FileOutputStream(fd);
433        final PrintWriter pw = new FastPrintWriter(fout);
434        Thread thr = new Thread("Binder.dumpAsync") {
435            public void run() {
436                try {
437                    dump(fd, pw, args);
438                } finally {
439                    pw.flush();
440                }
441            }
442        };
443        thr.start();
444    }
445
446    /**
447     * Print the object's state into the given stream.
448     *
449     * @param fd The raw file descriptor that the dump is being sent to.
450     * @param fout The file to which you should dump your state.  This will be
451     * closed for you after you return.
452     * @param args additional arguments to the dump request.
453     */
454    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
455    }
456
457    /**
458     * @param in The raw file descriptor that an input data stream can be read from.
459     * @param out The raw file descriptor that normal command messages should be written to.
460     * @param err The raw file descriptor that command error messages should be written to.
461     * @param args Command-line arguments.
462     * @param resultReceiver Called when the command has finished executing, with the result code.
463     * @throws RemoteException
464     * @hide
465     */
466    public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
467            String[] args, ResultReceiver resultReceiver) throws RemoteException {
468        onShellCommand(in, out, err, args, resultReceiver);
469    }
470
471    /**
472     * Handle a call to {@link #shellCommand}.  The default implementation simply prints
473     * an error message.  Override and replace with your own.
474     * <p class="caution">Note: no permission checking is done before calling this method; you must
475     * apply any security checks as appropriate for the command being executed.
476     * Consider using {@link ShellCommand} to help in the implementation.</p>
477     * @hide
478     */
479    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
480            String[] args, ResultReceiver resultReceiver) throws RemoteException {
481        FileOutputStream fout = new FileOutputStream(err != null ? err : out);
482        PrintWriter pw = new FastPrintWriter(fout);
483        pw.println("No shell command implementation.");
484        pw.flush();
485        resultReceiver.send(0, null);
486    }
487
488    /**
489     * Default implementation rewinds the parcels and calls onTransact.  On
490     * the remote side, transact calls into the binder to do the IPC.
491     */
492    public final boolean transact(int code, Parcel data, Parcel reply,
493            int flags) throws RemoteException {
494        if (false) Log.v("Binder", "Transact: " + code + " to " + this);
495
496        if (data != null) {
497            data.setDataPosition(0);
498        }
499        boolean r = onTransact(code, data, reply, flags);
500        if (reply != null) {
501            reply.setDataPosition(0);
502        }
503        return r;
504    }
505
506    /**
507     * Local implementation is a no-op.
508     */
509    public void linkToDeath(DeathRecipient recipient, int flags) {
510    }
511
512    /**
513     * Local implementation is a no-op.
514     */
515    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
516        return true;
517    }
518
519    protected void finalize() throws Throwable {
520        try {
521            destroy();
522        } finally {
523            super.finalize();
524        }
525    }
526
527    static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
528        if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
529            // Trying to send > 800k, this is way too much
530            StringBuilder sb = new StringBuilder();
531            sb.append(msg);
532            sb.append(": on ");
533            sb.append(obj);
534            sb.append(" calling ");
535            sb.append(code);
536            sb.append(" size ");
537            sb.append(parcel.dataSize());
538            sb.append(" (data: ");
539            parcel.setDataPosition(0);
540            sb.append(parcel.readInt());
541            sb.append(", ");
542            sb.append(parcel.readInt());
543            sb.append(", ");
544            sb.append(parcel.readInt());
545            sb.append(")");
546            Slog.wtfStack(TAG, sb.toString());
547        }
548    }
549
550    private native final void init();
551    private native final void destroy();
552
553    // Entry point from android_util_Binder.cpp's onTransact
554    private boolean execTransact(int code, long dataObj, long replyObj,
555            int flags) {
556        Parcel data = Parcel.obtain(dataObj);
557        Parcel reply = Parcel.obtain(replyObj);
558        // theoretically, we should call transact, which will call onTransact,
559        // but all that does is rewind it, and we just got these from an IPC,
560        // so we'll just call it directly.
561        boolean res;
562        // Log any exceptions as warnings, don't silently suppress them.
563        // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
564        try {
565            res = onTransact(code, data, reply, flags);
566        } catch (RemoteException|RuntimeException e) {
567            if (LOG_RUNTIME_EXCEPTION) {
568                Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
569            }
570            if ((flags & FLAG_ONEWAY) != 0) {
571                if (e instanceof RemoteException) {
572                    Log.w(TAG, "Binder call failed.", e);
573                } else {
574                    Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
575                }
576            } else {
577                reply.setDataPosition(0);
578                reply.writeException(e);
579            }
580            res = true;
581        } catch (OutOfMemoryError e) {
582            // Unconditionally log this, since this is generally unrecoverable.
583            Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
584            RuntimeException re = new RuntimeException("Out of memory", e);
585            reply.setDataPosition(0);
586            reply.writeException(re);
587            res = true;
588        }
589        checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
590        reply.recycle();
591        data.recycle();
592
593        // Just in case -- we are done with the IPC, so there should be no more strict
594        // mode violations that have gathered for this thread.  Either they have been
595        // parceled and are now in transport off to the caller, or we are returning back
596        // to the main transaction loop to wait for another incoming transaction.  Either
597        // way, strict mode begone!
598        StrictMode.clearGatheredViolations();
599
600        return res;
601    }
602}
603
604final class BinderProxy implements IBinder {
605    public native boolean pingBinder();
606    public native boolean isBinderAlive();
607
608    public IInterface queryLocalInterface(String descriptor) {
609        return null;
610    }
611
612    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
613        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
614        if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
615        return transactNative(code, data, reply, flags);
616    }
617
618    public native String getInterfaceDescriptor() throws RemoteException;
619    public native boolean transactNative(int code, Parcel data, Parcel reply,
620            int flags) throws RemoteException;
621    public native void linkToDeath(DeathRecipient recipient, int flags)
622            throws RemoteException;
623    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
624
625    public void dump(FileDescriptor fd, String[] args) throws RemoteException {
626        Parcel data = Parcel.obtain();
627        Parcel reply = Parcel.obtain();
628        data.writeFileDescriptor(fd);
629        data.writeStringArray(args);
630        try {
631            transact(DUMP_TRANSACTION, data, reply, 0);
632            reply.readException();
633        } finally {
634            data.recycle();
635            reply.recycle();
636        }
637    }
638
639    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
640        Parcel data = Parcel.obtain();
641        Parcel reply = Parcel.obtain();
642        data.writeFileDescriptor(fd);
643        data.writeStringArray(args);
644        try {
645            transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
646        } finally {
647            data.recycle();
648            reply.recycle();
649        }
650    }
651
652    public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
653            String[] args, ResultReceiver resultReceiver) throws RemoteException {
654        Parcel data = Parcel.obtain();
655        Parcel reply = Parcel.obtain();
656        data.writeFileDescriptor(in);
657        data.writeFileDescriptor(out);
658        data.writeFileDescriptor(err);
659        data.writeStringArray(args);
660        resultReceiver.writeToParcel(data, 0);
661        try {
662            transact(SHELL_COMMAND_TRANSACTION, data, reply, 0);
663            reply.readException();
664        } finally {
665            data.recycle();
666            reply.recycle();
667        }
668    }
669
670    BinderProxy() {
671        mSelf = new WeakReference(this);
672    }
673
674    @Override
675    protected void finalize() throws Throwable {
676        try {
677            destroy();
678        } finally {
679            super.finalize();
680        }
681    }
682
683    private native final void destroy();
684
685    private static final void sendDeathNotice(DeathRecipient recipient) {
686        if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
687        try {
688            recipient.binderDied();
689        }
690        catch (RuntimeException exc) {
691            Log.w("BinderNative", "Uncaught exception from death notification",
692                    exc);
693        }
694    }
695
696    final private WeakReference mSelf;
697    private long mObject;
698    private long mOrgue;
699}
700