blob: 7fdac1fcde64462a3dc54a680c524cc6ce8993a1 [file] [log] [blame]
// Copyright (C) 2025 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Rust interface to the dropbox service.
use anyhow::Result;
use binder::{wait_for_interface, Strong};
use dropboxmanager_aidl::aidl::com::android::internal::os::IDropBoxManagerService::IDropBoxManagerService;
const INTERFACE_NAME: &str = "dropbox";
/// Interface to the DropBox system service.
pub struct DropBoxManager {
binder: Strong<dyn IDropBoxManagerService>,
}
impl DropBoxManager {
/// Acquires the underlying binder interface.
pub fn new() -> Result<Self> {
Ok(Self { binder: wait_for_interface(INTERFACE_NAME)? })
}
/// Creates a dropbox entry with the supplied tag. The supplied text is passed as bytes to create the file contents.
pub fn add_text(&self, tag: &str, text: &str) -> Result<()> {
self.binder.addData(tag, text.as_bytes(), 2 /* DropBoxManager.java IS_TEXT */)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::path::PathBuf;
const DROPBOX_PATH: &str = "/data/system/dropbox";
const TAG: &str = "foo";
const CONTENT: &str = "bar\nbaz\n";
#[test]
fn add_text() {
let _ = find_dropbox_files(true).unwrap();
let manager = DropBoxManager::new().unwrap();
manager.add_text(TAG, CONTENT).unwrap();
let path_buf = find_dropbox_files(false).unwrap().unwrap();
let content = fs::read_to_string(path_buf.as_path()).unwrap();
assert_eq!(content, CONTENT);
}
fn find_dropbox_files(delete_them: bool) -> Result<Option<PathBuf>> {
let mut found = None;
for entry in fs::read_dir(DROPBOX_PATH)? {
let entry = entry?;
let path_buf = entry.path();
if !path_buf.is_file() {
continue;
}
let Some(filename) = path_buf.file_name() else {
continue;
};
let filename = filename.to_string_lossy();
if !filename.starts_with(TAG) {
continue;
}
found = Some(path_buf.clone());
if delete_them {
fs::remove_file(&path_buf)?;
} else {
break;
}
}
Ok(found)
}
}