• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.os;
18 
19 import android.util.Log;
20 
21 import java.io.FileDescriptor;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.PrintWriter;
25 import java.lang.ref.WeakReference;
26 import 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  */
43 public 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      */
getCallingPid()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      */
getCallingUid()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      */
getOrigCallingUid()84     public static final int getOrigCallingUid() {
85         if (UserId.MU_ENABLED) {
86             return getOrigCallingUidNative();
87         } else {
88             return getCallingUid();
89         }
90     }
91 
getOrigCallingUidNative()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      */
getOrigCallingUser()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      */
clearCallingIdentity()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      */
restoreCallingIdentity(long token)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      */
setThreadStrictModePolicy(int policyMask)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      */
getThreadStrictModePolicy()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      */
flushPendingCommands()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      */
joinThreadPool()170     public static final native void joinThreadPool();
171 
172     /**
173      * Default constructor initializes the object.
174      */
Binder()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      */
attachInterface(IInterface owner, String descriptor)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      */
getInterfaceDescriptor()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      */
pingBinder()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      */
isBinderAlive()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      */
queryLocalInterface(String descriptor)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      */
onTransact(int code, Parcel data, Parcel reply, int flags)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      */
dump(FileDescriptor fd, String[] args)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      */
dumpAsync(final FileDescriptor fd, final String[] args)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      */
dump(FileDescriptor fd, PrintWriter fout, String[] args)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      */
transact(int code, Parcel data, Parcel reply, int flags)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      */
linkToDeath(DeathRecipient recipient, int flags)336     public void linkToDeath(DeathRecipient recipient, int flags) {
337     }
338 
339     /**
340      * Local implementation is a no-op.
341      */
unlinkToDeath(DeathRecipient recipient, int flags)342     public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
343         return true;
344     }
345 
finalize()346     protected void finalize() throws Throwable {
347         try {
348             destroy();
349         } finally {
350             super.finalize();
351         }
352     }
353 
init()354     private native final void init();
destroy()355     private native final void destroy();
356 
357     // Entry point from android_util_Binder.cpp's onTransact
execTransact(int code, int dataObj, int replyObj, int flags)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 
388 final class BinderProxy implements IBinder {
pingBinder()389     public native boolean pingBinder();
isBinderAlive()390     public native boolean isBinderAlive();
391 
queryLocalInterface(String descriptor)392     public IInterface queryLocalInterface(String descriptor) {
393         return null;
394     }
395 
getInterfaceDescriptor()396     public native String getInterfaceDescriptor() throws RemoteException;
transact(int code, Parcel data, Parcel reply, int flags)397     public native boolean transact(int code, Parcel data, Parcel reply,
398             int flags) throws RemoteException;
linkToDeath(DeathRecipient recipient, int flags)399     public native void linkToDeath(DeathRecipient recipient, int flags)
400             throws RemoteException;
unlinkToDeath(DeathRecipient recipient, int flags)401     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
402 
dump(FileDescriptor fd, String[] args)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 
dumpAsync(FileDescriptor fd, String[] args)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 
BinderProxy()431     BinderProxy() {
432         mSelf = new WeakReference(this);
433     }
434 
435     @Override
finalize()436     protected void finalize() throws Throwable {
437         try {
438             destroy();
439         } finally {
440             super.finalize();
441         }
442     }
443 
destroy()444     private native final void destroy();
445 
sendDeathNotice(DeathRecipient recipient)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