tauri_plugin_android_fs/api/
private_storage.rs

1use crate::*;
2
3
4/// API of file storage intended for the app’s use only.  
5/// 
6/// # Examples
7/// ```
8/// fn example(app: &tauri::AppHandle) {
9///     use tauri_plugin_android_fs::AndroidFsExt as _;
10/// 
11///     let api = app.android_fs();
12///     let private_storage = api.private_storage();
13/// }
14/// ```
15pub struct PrivateStorage<'a, R: tauri::Runtime>(
16    #[allow(unused)]
17    pub(crate) &'a AndroidFs<R>
18);
19
20impl<'a, R: tauri::Runtime> PrivateStorage<'a, R> {
21
22    /// Get the absolute path of the specified directory.  
23    /// App can fully manage entries within this directory.   
24    /// 
25    /// This function does **not** create any directories; it only constructs the path.
26    ///
27    /// These entries will be deleted when the app is uninstalled and may also be deleted at the user’s initialising request.  
28    /// When using [`PrivateDir::Cache`], the system will automatically delete entries as disk space is needed elsewhere on the device.   
29    /// 
30    /// Since the returned paths can change when the app is moved to an adopted storage device, 
31    /// only relative paths should be stored.
32    /// 
33    /// # Support
34    /// All Android version.
35    pub fn resolve_path(
36        &self, 
37        dir: PrivateDir
38    ) -> crate::Result<std::path::PathBuf> {
39
40        on_android!({
41            impl_de!(struct Paths {
42                data: String, 
43                cache: String
44            });
45        
46            static PATHS: std::sync::OnceLock<Paths> = std::sync::OnceLock::new();
47
48            if PATHS.get().is_none() {
49                let _ = PATHS.set(
50                    self.0.api.run_mobile_plugin::<Paths>("getPrivateBaseDirAbsolutePaths", "")?
51                );
52            }
53            let paths = PATHS.get().expect("Should call 'set' before 'get'");
54
55            Ok(match dir {
56                PrivateDir::Data => std::path::PathBuf::from(paths.data.to_owned()),
57                PrivateDir::Cache => std::path::PathBuf::from(paths.cache.to_owned()),
58            })
59        })
60    }
61
62    #[deprecated = "Use FileUri::from_path instead"]
63    pub fn resolve_uri(
64        &self, 
65        dir: PrivateDir,
66        relative_path: impl AsRef<std::path::Path>
67    ) -> crate::Result<FileUri> {
68
69        on_android!({
70            let mut path = self.resolve_path(dir)?;
71            path.push(validate_relative_path(relative_path.as_ref())?);
72            Ok(path.into())
73        })
74    }
75}
76
77#[allow(unused)]
78impl<'a, R: tauri::Runtime> PrivateStorage<'a, R> {
79
80    pub(crate) fn create_new_tmp_file(&self) -> crate::Result<(std::fs::File, std::path::PathBuf)> {
81        on_android!({
82            let tmp_file_path = {
83                use std::sync::atomic::{AtomicUsize, Ordering};
84
85                static COUNTER: AtomicUsize = AtomicUsize::new(0);
86                let id = COUNTER.fetch_add(1, Ordering::Relaxed);
87
88                let tmp_dir_path = self.resolve_tmp_dir()?;
89                let _ = std::fs::create_dir_all(&tmp_dir_path);
90            
91                tmp_dir_path.join(format!("{id}"))
92            };
93            
94            let tmp_file = std::fs::File::create_new(&tmp_file_path)?;
95
96            Ok((tmp_file, tmp_file_path))
97        })
98    }
99
100    pub(crate) fn remove_all_tmp_files(&self) -> crate::Result<()> {
101        on_android!({
102            match std::fs::remove_dir_all(self.resolve_tmp_dir()?) {
103                Ok(_) => Ok(()),
104                Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
105                Err(e) => Err(e.into()),
106            }
107        })
108    }
109
110    pub(crate) fn resolve_tmp_dir(&self) -> crate::Result<std::path::PathBuf> {
111        on_android!({
112            const TMP_DIR_RELATIVE_PATH: &str = "pluginAndroidFs-tmpDir-01K486FKQ2BZSBGFD34RFH9FWJ";
113
114            let mut path = self.resolve_path(PrivateDir::Cache)?;
115            path.push(TMP_DIR_RELATIVE_PATH);
116            Ok(path)
117        })
118    }
119}