tauri_plugin_android_fs/api/private_storage.rs
1use sync_async::sync_async;
2use crate::*;
3use super::*;
4
5
6/// API of file storage intended for the app’s use only.
7///
8/// # Examples
9/// ```no_run
10/// fn example(app: &tauri::AppHandle) {
11/// use tauri_plugin_android_fs::AndroidFsExt as _;
12///
13/// let api = app.android_fs();
14/// let private_storage = api.private_storage();
15/// }
16/// ```
17#[sync_async]
18pub struct PrivateStorage<'a, R: tauri::Runtime> {
19 #[cfg(target_os = "android")]
20 pub(crate) handle: &'a tauri::plugin::PluginHandle<R>,
21
22 #[cfg(not(target_os = "android"))]
23 #[allow(unused)]
24 pub(crate) handle: &'a std::marker::PhantomData<fn() -> R>,
25}
26
27#[cfg(target_os = "android")]
28#[sync_async(
29 use(if_sync) impls::SyncImpls as Impls;
30 use(if_async) impls::AsyncImpls as Impls;
31)]
32impl<'a, R: tauri::Runtime> PrivateStorage<'a, R> {
33
34 #[always_sync]
35 fn impls(&self) -> Impls<'_, R> {
36 Impls { handle: &self.handle }
37 }
38}
39
40#[sync_async(
41 use(if_async) api_async::{AndroidFs, FileOpener, FilePicker, PublicStorage};
42 use(if_sync) api_sync::{AndroidFs, FileOpener, FilePicker, PublicStorage};
43)]
44impl<'a, R: tauri::Runtime> PrivateStorage<'a, R> {
45
46 /// Get an absolute path of the app-specific directory on the internal storage.
47 /// App can fully manage entries within this directory via [`std::fs`] and etc.
48 ///
49 /// This function does **not** create any directories; it only constructs the path.
50 ///
51 /// Since these locations may contain files created by other Tauri plugins or webview systems,
52 /// it is recommended to add a subdirectory with a unique name.
53 ///
54 /// These entries will be deleted when the app is uninstalled and may also be deleted at the user’s initialising request.
55 ///
56 /// When using [`PrivateDir::Cache`], the system will automatically delete entries as disk space is needed elsewhere on the device.
57 /// But you should not rely on this. The cache should be explicitly cleared by yourself.
58 ///
59 /// The system prevents other apps and user from accessing these locations.
60 /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.
61 ///
62 /// Since the returned paths can change when the app is moved to an [adopted storage](https://source.android.com/docs/core/storage/adoptable),
63 /// only relative paths should be stored.
64 ///
65 /// # Note
66 /// This provides a separate area for each user in a multi-user environment.
67 ///
68 /// # Support
69 /// All Android version.
70 #[maybe_async]
71 pub fn resolve_path(
72 &self,
73 dir: PrivateDir
74 ) -> Result<std::path::PathBuf> {
75
76 #[cfg(not(target_os = "android"))] {
77 Err(Error::NOT_ANDROID)
78 }
79 #[cfg(target_os = "android")] {
80 self.impls().private_dir_path(dir).map(Clone::clone)
81 }
82 }
83
84 /// See [`PrivateStorage::resolve_path`] and [`FileUri::from_path`]
85 #[maybe_async]
86 pub fn resolve_uri(
87 &self,
88 dir: PrivateDir,
89 relative_path: impl AsRef<std::path::Path>
90 ) -> Result<FileUri> {
91
92 #[cfg(not(target_os = "android"))] {
93 Err(Error::NOT_ANDROID)
94 }
95 #[cfg(target_os = "android")] {
96 let mut path = self.resolve_path(dir).await?;
97 path.push(relative_path.as_ref());
98 Ok(path.into())
99 }
100 }
101
102 /// Creates a new temporary file and returns its file, path, and URI.
103 /// App can fully manage it via [`std::fs`] and etc.
104 ///
105 /// This file remains valid until the application exits.
106 /// It will be deleted when the application starts,
107 /// and may be deleted when the application exits.
108 ///
109 /// # Inner
110 /// The file will be placed in the `pluginAndroidFs-tempDir-01K486FKQ2BZSBGFD34RFH9FWJ`
111 /// directory inside [`PrivateStorage::resolve_path`] with [`PrivateDir::NoBackupData`].
112 /// It directory will be deleted by this plugin when the application starts,
113 /// and may be deleted when the application exits.
114 ///
115 /// # Support
116 /// All Android version.
117 #[maybe_async]
118 pub fn create_new_temp_file(&self) -> Result<(std::fs::File, std::path::PathBuf, FileUri)> {
119 #[cfg(not(target_os = "android"))] {
120 Err(Error::NOT_ANDROID)
121 }
122 #[cfg(target_os = "android")] {
123 self.impls().create_new_temp_file().await
124 }
125 }
126
127 /// Creates a new temporary file and returns its file,
128 /// a guard that removes the file on drop, the file path, and its URI.
129 /// App can fully manage it via [`std::fs`] and etc.
130 ///
131 /// This file remains valid until the application exits.
132 /// It will be deleted when the application starts,
133 /// and may be deleted when the application exits.
134 ///
135 /// # Inner
136 /// The file will be placed in the `pluginAndroidFs-tempDir-01K486FKQ2BZSBGFD34RFH9FWJ`
137 /// directory inside [`PrivateStorage::resolve_path`] with [`PrivateDir::NoBackupData`].
138 /// It directory will be deleted by this plugin when the application starts,
139 /// and may be deleted when the application exits.
140 ///
141 /// # Support
142 /// All Android version.
143 #[maybe_async]
144 pub fn create_new_temp_file_with_guard(&self) -> Result<(std::fs::File, TempFileGuard, std::path::PathBuf, FileUri)> {
145 #[cfg(not(target_os = "android"))] {
146 Err(Error::NOT_ANDROID)
147 }
148 #[cfg(target_os = "android")] {
149 let (file, path, uri) = self.impls().create_new_temp_file().await?;
150 let guard = TempFileGuard { path: path.clone() };
151 Ok((file, guard, path, uri))
152 }
153 }
154
155 /// Removes all temporary files.
156 ///
157 /// See [`PrivateStorage::create_new_temp_file`].
158 ///
159 /// # Support
160 /// All Android version.
161 #[maybe_async]
162 pub fn remove_all_temp_files(&self) -> Result<()> {
163 #[cfg(not(target_os = "android"))] {
164 Err(Error::NOT_ANDROID)
165 }
166 #[cfg(target_os = "android")] {
167 self.impls().remove_all_temp_files().await
168 }
169 }
170}