blob: 0ba4a2327fa311a7315e7fd46bc84e89f2f7184a [file] [log] [blame]
package com.android.clockwork.bluetooth;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.annotation.Resetter;
import org.robolectric.shadow.api.Shadow;
/**
* Enables using ParcelFileDescriptor.createSocketPair in robolectric tests.
*
* <p>Uses in-memory input and output streams for the descriptor.
*/
@Implements(ParcelFileDescriptor.class)
public class ShadowParcelFileDescriptor {
private @RealObject ParcelFileDescriptor realObject;
private PipedOutputStream outputStream;
private PipedInputStream inputStream;
/** Returns the stream that is used to write data to this descriptor. */
public OutputStream getOutputStream() {
return outputStream;
}
/** Returns the stream that is used to read data from this descriptor. */
public InputStream getInputStream() {
return inputStream;
}
@Implementation
protected static ParcelFileDescriptor[] createSocketPair(int option) throws IOException {
ShadowParcelFileDescriptor fd1 = create();
ShadowParcelFileDescriptor fd2 = create();
fd1.inputStream = new PipedInputStream(fd2.outputStream);
fd2.inputStream = new PipedInputStream(fd1.outputStream);
return new ParcelFileDescriptor[] {fd1.realObject, fd2.realObject};
}
private static ShadowParcelFileDescriptor create() {
ParcelFileDescriptor fd = new ParcelFileDescriptor(new FileDescriptor());
ShadowParcelFileDescriptor shadow = Shadow.extract(fd);
shadow.outputStream = new PipedOutputStream();
shadows.add(shadow);
return shadow;
}
@Implementation
protected ParcelFileDescriptor dup() {
// Does not really duplicate the descriptor but this is enough for the tests.
return realObject;
}
@Implementation
protected void close() throws IOException {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
@Resetter
public static void resetShadows() {
shadows.clear();
}
private static final List<ShadowParcelFileDescriptor> shadows = new ArrayList<>();
/**
* Returns the shadow that wraps the given file descriptor or null if the shadow is not found.
*
* <p>NOTE: Only works if the descriptor was created with {@link #create} function.
*/
static ShadowParcelFileDescriptor findShadow(FileDescriptor fd) {
for (ShadowParcelFileDescriptor shadow : shadows) {
if (shadow.realObject.getFileDescriptor() == fd) {
return shadow;
}
}
return null;
}
}