@@ -42,8 +42,51 @@ export class AndroidApplicationManager extends ApplicationManagerBase {
4242 }
4343
4444 public async getInstalledApplications ( ) : Promise < string [ ] > {
45- const result =
46- ( await this . adb . executeShellCommand ( [ "pm" , "list" , "packages" ] ) ) || "" ;
45+ let result = "" ;
46+ try {
47+ result = await this . adb . executeShellCommand ( [ "pm" , "list" , "packages" ] ) ;
48+ } catch ( err ) {
49+ /**
50+ * on some devices (Samsung) listing packages is prevented by a permission error
51+ * notably, some system apps (bloatware) is installed under user 150
52+ * and listing these packages results in a permission error.
53+ * if this happens, we have to first list all the users, and then loop through
54+ * all the users and trying to list packages for that specific user, ignoring
55+ * any errors. These are all then concatenated together and parsed normally.
56+ * This is a slower operation, so we only do it in case listing failed in the first place.
57+ */
58+ const userIDs : string [ ] = [ ] ;
59+ const users = await this . adb . executeShellCommand ( [ "pm" , "list" , "users" ] ) ;
60+ /**
61+ * Users:
62+ * UserInfo{0:Owner:c13} running
63+ */
64+
65+ const userIDRegex = / U s e r I n f o { ( \d + ) [: } ] / ;
66+ users . split ( EOL ) . forEach ( ( line : string ) => {
67+ const [ , userID ] = line . match ( userIDRegex ) ?? [ ] ;
68+
69+ if ( userID ) {
70+ userIDs . push ( userID ) ;
71+ }
72+ } ) ;
73+
74+ for ( let id of userIDs ) {
75+ try {
76+ result +=
77+ EOL +
78+ ( await this . adb . executeShellCommand ( [
79+ "pm" ,
80+ "list" ,
81+ "packages" ,
82+ "--user" ,
83+ id ,
84+ ] ) ) ;
85+ } catch ( err ) {
86+ // ignore - likely permission denied.
87+ }
88+ }
89+ }
4790 const regex = / p a c k a g e : ( .+ ) / ;
4891 return result
4992 . split ( EOL )
0 commit comments