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");
  4. // Open a file and put the birthday info in it.
  5. let mut file = File::create("/data/local/tmp/birthday.info").unwrap();
  6. writeln!(file, "{name}")?;
  7. writeln!(file, "{years}")?;
  8. // Create a `ParcelFileDescriptor` from the file and send it.
  9. let file = ParcelFileDescriptor::new(file);
  10. service.wishFromFile(&file)?;
  11. }

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");
  14. let mut contents = String::new();
  15. info_file.read_to_string(&mut contents).unwrap();
  16. let mut lines = contents.lines();
  17. let name = lines.next().unwrap();
  18. let years: i32 = lines.next().unwrap().parse().unwrap();
  19. Ok(format!("Happy Birthday {name}, congratulations with the {years} years!"))
  20. }
  21. }
  • 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.