android_tools/adb/
adb_shell_pm.rs

1use crate::error::*;
2use std::{
3    path::{Path, PathBuf},
4    process::Command,
5};
6
7use super::InstallLocation;
8
9#[derive(Clone, Default)]
10pub struct AdbShellPm {
11    list_packages: Option<String>,
12    list_permission_groups: Option<String>,
13    list_permission: bool,
14    list_instrumentation: bool,
15    list_features: bool,
16    list_libraries: bool,
17    list_users: bool,
18    path_package: Option<PathBuf>,
19    install_path: Option<PathBuf>,
20    uninstall: Option<PathBuf>,
21    clear: Option<PathBuf>,
22    enable: Option<PathBuf>,
23    disable: Option<PathBuf>,
24    disable_user: Option<PathBuf>,
25    grant: Option<String>,
26    revoke: Option<String>,
27    set_install_location: Option<InstallLocation>,
28    get_install_location: Option<InstallLocation>,
29    install_location: Option<InstallLocation>,
30    set_permission_enforced: bool,
31    trim_caches: Option<PathBuf>,
32    create_user: Option<String>,
33    remove_user: Option<String>,
34    get_max_users: bool,
35    f: bool,
36    d: bool,
37    e: bool,
38    s: bool,
39    third_party: bool,
40    i: bool,
41    u: bool,
42    g: bool,
43    r: bool,
44    t: bool,
45    k: bool,
46    fastdeploy: bool,
47    no_incremental: bool,
48    user: Option<String>,
49}
50
51impl AdbShellPm {
52    pub fn new() -> Self {
53        Self {
54            ..Default::default()
55        }
56    }
57
58    /// Prints all packages, optionally only those whose package name contains
59    /// the text in filter.
60    ///
61    /// Options:
62    ///
63    /// * `-f`: See their associated file.
64    /// * `-d`: Filter to only show disabled packages.
65    /// * `-e`: Filter to only show enabled packages.
66    /// * `-s`: Filter to only show system packages.
67    /// * `-3`: Filter to only show third party packages.
68    /// * `-i`: See the installer for the packages.
69    /// * `-u`: Also include uninstalled packages.
70    /// * `--user user_id`: The user space to query.
71    pub fn list_packages(&mut self, list_packages: String) -> &mut Self {
72        self.list_packages = Some(list_packages);
73        self
74    }
75
76    /// Prints all known permission groups.
77    pub fn list_permission_groups(&mut self, list_permission_groups: String) -> &mut Self {
78        self.list_permission_groups = Some(list_permission_groups);
79        self
80    }
81
82    /// Prints all known permissions, optionally only those in group.
83    ///
84    /// Options:
85    ///
86    /// * `-g`: Organize by group.
87    /// * `-f`: Print all information.
88    /// * `-s`: Short summary.
89    /// * `-d`: Only list dangerous permissions.
90    /// * `-u`: List only the permissions users will see.
91    pub fn list_permission(&mut self, list_permission: bool) -> &mut Self {
92        self.list_permission = list_permission;
93        self
94    }
95
96    /// List all test packages.
97    ///
98    /// Options:
99    ///
100    /// * `-f`: List the APK file for the test package.
101    /// * `target_package`: List test packages for only this app.
102    pub fn list_instrumentation(&mut self, list_instrumentation: bool) -> &mut Self {
103        self.list_instrumentation = list_instrumentation;
104        self
105    }
106
107    /// Prints all features of the system.
108    pub fn list_features(&mut self, list_features: bool) -> &mut Self {
109        self.list_features = list_features;
110        self
111    }
112
113    /// Prints all the libraries supported by the current device.
114    pub fn list_libraries(&mut self, list_libraries: bool) -> &mut Self {
115        self.list_libraries = list_libraries;
116        self
117    }
118
119    /// Prints all users on the system.
120    pub fn list_users(&mut self, list_users: bool) -> &mut Self {
121        self.list_users = list_users;
122        self
123    }
124
125    /// Print the path to the APK of the given package.
126    pub fn path_package(&mut self, path_package: &Path) -> &mut Self {
127        self.path_package = Some(path_package.to_owned());
128        self
129    }
130
131    /// Installs a package (specified by path) to the system.
132    ///
133    /// Options:
134    /// * `-r`: Reinstall an existing app, keeping its data.
135    /// * `-t`: Allow test APKs to be installed. Gradle generates a test APK when
136    /// you have only run or debugged your app or have used the Android Studio
137    /// Build > Build APK command. If the APK is built using a developer preview
138    /// SDK (if the targetSdkVersion is a letter instead of a number), you must
139    /// include the -t option with the install command if you are installing a
140    /// test APK.
141    /// * `-i installer_package_name`: Specify the installer package name.
142    /// * `--install-location location`: Sets the install location using one of
143    /// the following values:
144    ///     * `0`: Use the default install location
145    ///     * `1`: Install on internal device storage
146    ///     * `2`: Install on external media
147    /// * `-f`: Install package on the internal system memory.
148    /// * `-d`: Allow version code downgrade.
149    /// * `-g`: Grant all permissions listed in the app manifest.
150    /// * `--fastdeploy`: Quickly update an installed package by only updating the
151    /// parts of the APK that changed.
152    /// * `--incremental`: Installs enough of the APK to launch the app while
153    /// streaming the remaining data in the background. To use this feature, you
154    /// must sign the APK, create an [`APK Signature Scheme v4 file`], and place this
155    /// file in the same directory as the APK. This feature is only supported on
156    /// certain devices. This option forces adb to use the feature or fail if it
157    /// is not supported (with verbose information on why it failed). Append the
158    /// `--wait` option to wait until the APK is fully installed before granting
159    /// access to the APK.
160    pub fn install_path(&mut self, install_path: &Path) -> &mut Self {
161        self.install_path = Some(install_path.to_owned());
162        self
163    }
164
165    /// Removes a package from the system.
166    ///
167    /// Options:
168    /// * `-k`: Keep the data and cache directories around after package removal.
169    pub fn uninstall(&mut self, uninstall: &Path) -> &mut Self {
170        self.uninstall = Some(uninstall.to_owned());
171        self
172    }
173
174    /// Deletes all data associated with a package.
175    pub fn clear(&mut self, clear: &Path) -> &mut Self {
176        self.clear = Some(clear.to_owned());
177        self
178    }
179
180    /// Enable the given package or component (written as "package/class").
181    pub fn enable(&mut self, enable: &Path) -> &mut Self {
182        self.enable = Some(enable.to_owned());
183        self
184    }
185
186    /// Disable the given package or component (written as "package/class").
187    pub fn disable(&mut self, disable: &Path) -> &mut Self {
188        self.disable = Some(disable.to_owned());
189        self
190    }
191
192    /// Options:
193    ///
194    /// `--user user_id`: The user to disable.
195    pub fn disable_user(&mut self, disable_user: &Path) -> &mut Self {
196        self.disable_user = Some(disable_user.to_owned());
197        self
198    }
199
200    /// Grant a permission to an app. On devices running Android 6.0 (API level 23)
201    /// and higher, the permission can be any permission declared in the app
202    /// manifest. On devices running Android 5.1 (API level 22) and lower, must be
203    /// an optional permission defined by the app.
204    pub fn grant(&mut self, grant: String) -> &mut Self {
205        self.grant = Some(grant);
206        self
207    }
208
209    /// Revoke a permission from an app. On devices running Android 6.0 (API level 23)
210    /// and higher, the permission can be any permission declared in the app manifest.
211    /// On devices running Android 5.1 (API level 22) and lower, must be an optional
212    /// permission defined by the app.
213    pub fn revoke(&mut self, revoke: String) -> &mut Self {
214        self.revoke = Some(revoke);
215        self
216    }
217
218    /// Changes the default install location. Location values:
219    /// * `0`: Auto: Let system decide the best location.
220    /// * `1`: Internal: install on internal device storage.
221    /// * `2`: External: on external media.
222    ///
223    /// ## Note
224    /// This is only intended for debugging; using this can cause apps to break and
225    /// other undesireable behavior.
226    pub fn set_install_location(&mut self, set_install_location: InstallLocation) -> &mut Self {
227        self.set_install_location = Some(set_install_location);
228        self
229    }
230
231    /// Returns the current install location. Return values:
232    /// * `0`: Auto: Let system decide the best location.
233    /// * `1`: Internal: install on internal device storage.
234    /// * `2`: External: on external media.
235    pub fn get_install_location(&mut self, get_install_location: InstallLocation) -> &mut Self {
236        self.get_install_location = Some(get_install_location);
237        self
238    }
239
240    /// Specifies whether the given permission should be enforced.
241    pub fn set_permission_enforced(&mut self, set_permission_enforced: bool) -> &mut Self {
242        self.set_permission_enforced = set_permission_enforced;
243        self
244    }
245
246    /// Trim cache files to reach the given free space.
247    pub fn trim_caches(&mut self, trim_caches: &Path) -> &mut Self {
248        self.trim_caches = Some(trim_caches.to_owned());
249        self
250    }
251
252    /// Create a new user with the given user_name, printing the new user identifier
253    /// of the user.
254    pub fn create_user(&mut self, create_user: String) -> &mut Self {
255        self.create_user = Some(create_user);
256        self
257    }
258
259    /// Remove the user with the given user_id, deleting all data associated with
260    /// that user
261    pub fn remove_user(&mut self, remove_user: String) -> &mut Self {
262        self.remove_user = Some(remove_user);
263        self
264    }
265
266    /// Prints the maximum number of users supported by the device.
267    pub fn get_max_users(&mut self, get_max_users: bool) -> &mut Self {
268        self.get_max_users = get_max_users;
269        self
270    }
271
272    pub fn f(&mut self, f: bool) -> &mut Self {
273        self.f = f;
274        self
275    }
276
277    pub fn d(&mut self, d: bool) -> &mut Self {
278        self.d = d;
279        self
280    }
281
282    pub fn e(&mut self, e: bool) -> &mut Self {
283        self.e = e;
284        self
285    }
286
287    pub fn s(&mut self, s: bool) -> &mut Self {
288        self.s = s;
289        self
290    }
291
292    pub fn third_party(&mut self, third_party: bool) -> &mut Self {
293        self.third_party = third_party;
294        self
295    }
296
297    pub fn i(&mut self, i: bool) -> &mut Self {
298        self.i = i;
299        self
300    }
301
302    pub fn u(&mut self, u: bool) -> &mut Self {
303        self.u = u;
304        self
305    }
306
307    pub fn g(&mut self, g: bool) -> &mut Self {
308        self.g = g;
309        self
310    }
311
312    pub fn r(&mut self, r: bool) -> &mut Self {
313        self.r = r;
314        self
315    }
316
317    pub fn t(&mut self, t: bool) -> &mut Self {
318        self.t = t;
319        self
320    }
321
322    pub fn k(&mut self, k: bool) -> &mut Self {
323        self.k = k;
324        self
325    }
326
327    pub fn fastdeploy(&mut self, fastdeploy: bool) -> &mut Self {
328        self.fastdeploy = fastdeploy;
329        self
330    }
331
332    pub fn no_incremental(&mut self, no_incremental: bool) -> &mut Self {
333        self.no_incremental = no_incremental;
334        self
335    }
336
337    pub fn user(&mut self, user: String) -> &mut Self {
338        self.user = Some(user);
339        self
340    }
341
342    pub fn run(&self) -> Result<()> {
343        let mut pm = Command::new("adb");
344        pm.arg("shell");
345        pm.arg("pm");
346        if let Some(list_packages) = &self.list_packages {
347            pm.arg("list packages").arg(list_packages);
348        }
349        if let Some(list_permission_groups) = &self.list_permission_groups {
350            pm.arg("list permission groups").arg(list_permission_groups);
351        }
352        if self.list_permission {
353            pm.arg("list permissions");
354        }
355        if self.list_instrumentation {
356            pm.arg("list instrumentation");
357        }
358        if self.list_features {
359            pm.arg("list features");
360        }
361        if self.list_libraries {
362            pm.arg("list libraries");
363        }
364        if self.list_users {
365            pm.arg("list users");
366        }
367        if let Some(path_package) = &self.path_package {
368            pm.arg("path").arg(path_package);
369        }
370        if let Some(install_path) = &self.install_path {
371            pm.arg("install").arg(install_path);
372        }
373        if let Some(uninstall) = &self.uninstall {
374            pm.arg("uninstall").arg(uninstall);
375        }
376        if let Some(clear) = &self.clear {
377            pm.arg("clear").arg(clear);
378        }
379        if let Some(enable) = &self.enable {
380            pm.arg("enable").arg(enable);
381        }
382        if let Some(disable) = &self.disable {
383            pm.arg("disable").arg(disable);
384        }
385        if let Some(disable_user) = &self.disable_user {
386            pm.arg("disable-user").arg(disable_user);
387        }
388        if let Some(grant) = &self.grant {
389            pm.arg("grant").arg(grant);
390        }
391        if let Some(revoke) = &self.revoke {
392            pm.arg("revoke").arg(revoke);
393        }
394        if let Some(set_install_location) = &self.set_install_location {
395            pm.arg("set-install-location")
396                .arg(set_install_location.to_string());
397        }
398        if let Some(get_install_location) = &self.get_install_location {
399            pm.arg("get-install-location")
400                .arg(get_install_location.to_string());
401        }
402        if let Some(install_location) = &self.install_location {
403            pm.arg("--install-location")
404                .arg(install_location.to_string());
405        }
406        if self.set_permission_enforced {
407            pm.arg("set-permission-enforced");
408        }
409        if let Some(trim_caches) = &self.trim_caches {
410            pm.arg("trim-caches").arg(trim_caches);
411        }
412        if let Some(create_user) = &self.create_user {
413            pm.arg("create-user").arg(create_user);
414        }
415        if let Some(remove_user) = &self.remove_user {
416            pm.arg("remove-user").arg(remove_user);
417        }
418        if self.get_max_users {
419            pm.arg("get-max-users");
420        }
421        if self.f {
422            pm.arg("-f");
423        }
424        if self.d {
425            pm.arg("-d");
426        }
427        if self.e {
428            pm.arg("-e");
429        }
430        if self.s {
431            pm.arg("-s");
432        }
433        if self.third_party {
434            pm.arg("-3");
435        }
436        if self.i {
437            pm.arg("-i");
438        }
439        if self.u {
440            pm.arg("-u");
441        }
442        if self.g {
443            pm.arg("-g");
444        }
445        if self.r {
446            pm.arg("-r");
447        }
448        if self.t {
449            pm.arg("-t");
450        }
451        if self.k {
452            pm.arg("-k");
453        }
454        if self.fastdeploy {
455            pm.arg("--fastdeploy");
456        }
457        if self.no_incremental {
458            pm.arg("--no-incremental");
459        }
460        if let Some(user) = &self.user {
461            pm.arg("--user").arg(user);
462        }
463        pm.output_err(true)?;
464        Ok(())
465    }
466}