1515 */
1616
1717package android .os ;
18+
19+ import dalvik .system .CloseGuard ;
20+
1821import java .io .Closeable ;
1922import java .io .File ;
2023import java .io .FileDescriptor ;
3134 */
3235public class ParcelFileDescriptor implements Parcelable , Closeable {
3336 private final FileDescriptor mFileDescriptor ;
34- private boolean mClosed ;
35- //this field is to create wrapper for ParcelFileDescriptor using another
36- //PartialFileDescriptor but avoid invoking close twice
37- //consider ParcelFileDescriptor A(fileDescriptor fd), ParcelFileDescriptor B(A)
38- //in this particular case fd.close might be invoked twice.
39- private final ParcelFileDescriptor mParcelDescriptor ;
37+
38+ /**
39+ * Wrapped {@link ParcelFileDescriptor}, if any. Used to avoid
40+ * double-closing {@link #mFileDescriptor}.
41+ */
42+ private final ParcelFileDescriptor mWrapped ;
43+
44+ private volatile boolean mClosed ;
45+
46+ private final CloseGuard mGuard = CloseGuard .get ();
4047
4148 /**
4249 * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
@@ -289,13 +296,15 @@ public int detachFd() {
289296 if (mClosed ) {
290297 throw new IllegalStateException ("Already closed" );
291298 }
292- if (mParcelDescriptor != null ) {
293- int fd = mParcelDescriptor .detachFd ();
299+ if (mWrapped != null ) {
300+ int fd = mWrapped .detachFd ();
294301 mClosed = true ;
302+ mGuard .close ();
295303 return fd ;
296304 }
297305 int fd = getFd ();
298306 mClosed = true ;
307+ mGuard .close ();
299308 Parcel .clearFileDescriptor (mFileDescriptor );
300309 return fd ;
301310 }
@@ -307,15 +316,16 @@ public int detachFd() {
307316 * @throws IOException
308317 * If an error occurs attempting to close this ParcelFileDescriptor.
309318 */
319+ @ Override
310320 public void close () throws IOException {
311- synchronized ( this ) {
312- if ( mClosed ) return ;
313- mClosed = true ;
314- }
315- if (mParcelDescriptor != null ) {
321+ if ( mClosed ) return ;
322+ mClosed = true ;
323+ mGuard . close () ;
324+
325+ if (mWrapped != null ) {
316326 // If this is a proxy to another file descriptor, just call through to its
317327 // close method.
318- mParcelDescriptor .close ();
328+ mWrapped .close ();
319329 } else {
320330 Parcel .closeFileDescriptor (mFileDescriptor );
321331 }
@@ -374,6 +384,9 @@ public String toString() {
374384
375385 @ Override
376386 protected void finalize () throws Throwable {
387+ if (mGuard != null ) {
388+ mGuard .warnIfOpen ();
389+ }
377390 try {
378391 if (!mClosed ) {
379392 close ();
@@ -384,21 +397,22 @@ protected void finalize() throws Throwable {
384397 }
385398
386399 public ParcelFileDescriptor (ParcelFileDescriptor descriptor ) {
387- super () ;
388- mParcelDescriptor = descriptor ;
389- mFileDescriptor = mParcelDescriptor . mFileDescriptor ;
400+ mWrapped = descriptor ;
401+ mFileDescriptor = mWrapped . mFileDescriptor ;
402+ mGuard . open ( "close" ) ;
390403 }
391404
392- /*package */ ParcelFileDescriptor ( FileDescriptor descriptor ) {
393- super ();
405+ /** {@hide} */
406+ public ParcelFileDescriptor ( FileDescriptor descriptor ) {
394407 if (descriptor == null ) {
395408 throw new NullPointerException ("descriptor must not be null" );
396409 }
410+ mWrapped = null ;
397411 mFileDescriptor = descriptor ;
398- mParcelDescriptor = null ;
412+ mGuard . open ( "close" ) ;
399413 }
400414
401- /* Parcelable interface */
415+ @ Override
402416 public int describeContents () {
403417 return Parcelable .CONTENTS_FILE_DESCRIPTOR ;
404418 }
@@ -408,6 +422,7 @@ public int describeContents() {
408422 * If {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set in flags,
409423 * the file descriptor will be closed after a copy is written to the Parcel.
410424 */
425+ @ Override
411426 public void writeToParcel (Parcel out , int flags ) {
412427 out .writeFileDescriptor (mFileDescriptor );
413428 if ((flags &PARCELABLE_WRITE_RETURN_VALUE ) != 0 && !mClosed ) {
@@ -421,12 +436,14 @@ public void writeToParcel(Parcel out, int flags) {
421436
422437 public static final Parcelable .Creator <ParcelFileDescriptor > CREATOR
423438 = new Parcelable .Creator <ParcelFileDescriptor >() {
439+ @ Override
424440 public ParcelFileDescriptor createFromParcel (Parcel in ) {
425441 return in .readFileDescriptor ();
426442 }
443+
444+ @ Override
427445 public ParcelFileDescriptor [] newArray (int size ) {
428446 return new ParcelFileDescriptor [size ];
429447 }
430448 };
431-
432449}
0 commit comments