Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbf7e077 authored by Matt Gilbride's avatar Matt Gilbride
Browse files

Add Rust interface for DropBoxManager

Change Iddadeb5a175e395982ea632194f433536936aa26 refactored
DropBoxManager to not use a hand crafted Parcelable and thus be
compatible with interface. This change leverages aidl_interface to
create a Rust `DropBoxManager` client for use code bases that need one.

Bug: 420949170
Bug: 368152571
Test: atest DropBoxManagerTestRust
Flag: EXEMPT library only, no new functionality on device.
Change-Id: I9e07aee2311cddd7d5906989f730589139bdf449
parent 1c6ac92e
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -112,6 +112,13 @@ aidl_interface {
        java: {
            enabled: false, // TODO(b/424186512) switch frameworks/base to using this as well, it uses core build **/*.aidl glob now
        },
        rust: {
            enabled: true,
            apex_available: [
                "//apex_available:platform",
                "com.android.virt",
            ],
        },
    },
}

@@ -296,8 +303,8 @@ java_library {
    name: "modules-utils-locallog",
    srcs: ["android/util/LocalLog.java"],
    libs: [
        "unsupportedappusage",
        "ravenwood-annotations-lib",
        "unsupportedappusage",
    ],
    sdk_version: "module_current",
    min_sdk_version: "30",
+34 −1
Original line number Diff line number Diff line
@@ -57,9 +57,42 @@ cc_library_shared {
    ],
}

rust_defaults {
    name: "libdropbox_rs_defaults",
    srcs: ["src/dropboxmanager.rs"],
    prefer_rlib: true,
    rustlibs: [
        "libanyhow",
        "libbinder_rs",
        "liblog_rust",
        "liblogger",
        "librustutils",
        "dropboxmanager_aidl-rust",
    ],
}

rust_library {
    name: "libdropbox_rs",
    crate_name: "dropbox_rs",
    defaults: ["libdropbox_rs_defaults"],
    visibility: [
        "//packages/modules/Virtualization:__subpackages__",
    ],
    apex_available: [
        "com.android.virt",
    ],
}

rust_test {
    name: "DropBoxManagerTestRust",
    team: "trendy_team_framework_bpm",
    defaults: ["libdropbox_rs_defaults"],
    require_root: true,
}

cc_test {
    name: "DropBoxManagerTestCpp",
    team: "trendy_team_foundations",
    team: "trendy_team_framework_bpm",
    srcs: [
        "test/DropBoxManagerTest.cpp",
    ],
+85 −0
Original line number Diff line number Diff line
// Copyright 2025, The ChromiumOS Authors
//
// 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)
    }
}