Sending Files

Files can be sent between Binder clients/servers using the ParcelFileDescriptor type:

birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl:

1. interface IBirthdayService {
2. /** The same thing, but loads info from a file. */
3. String wishFromFile(in ParcelFileDescriptor infoFile);
4. }

birthday_service/src/client.rs:

1. fn main() {
2. binder::ProcessState::start_thread_pool();
3. let service = connect().expect("Failed to connect to BirthdayService");

5. // Open a file and put the birthday info in it.
6. let mut file = File::create("/data/local/tmp/birthday.info").unwrap();
7. writeln!(file, "{name}")?;
8. writeln!(file, "{years}")?;

10. // Create a `ParcelFileDescriptor` from the file and send it.
11. let file = ParcelFileDescriptor::new(file);
12. service.wishFromFile(&file)?;
13. }

birthday_service/src/lib.rs:

1. impl IBirthdayService for BirthdayService {
2. fn wishFromFile(
3. &self,
4. info_file: &ParcelFileDescriptor,
5. ) -> binder::Result<String> {
6. // Convert the file descriptor to a `File`. `ParcelFileDescriptor` wraps
7. // an `OwnedFd`, which can be cloned and then used to create a `File`
8. // object.
9. let mut info_file = info_file
10. .as_ref()
11. .try_clone()
12. .map(File::from)
13. .expect("Invalid file handle");

15. let mut contents = String::new();
16. info_file.read_to_string(&mut contents).unwrap();

18. let mut lines = contents.lines();
19. let name = lines.next().unwrap();
20. let years: i32 = lines.next().unwrap().parse().unwrap();

22. Ok(format!("Happy Birthday {name}, congratulations with the {years} years!"))
23. }
24. }
  • ParcelFileDescriptor wraps an OwnedFd, and so can be created from a File (or any other type that wraps an OwnedFd), and can be used to create a new File handle on the other side.
  • Other types of file descriptors can be wrapped and sent, e.g. TCP, UDP, and UNIX sockets.