@@ -1415,21 +1415,15 @@ public static List<PackageInfoData> getApps(Context ctx, GetAppList appList) {
14151415 }
14161416 }
14171417 //use pm list packages -f -U --user 10
1418- int pkgManagerFlags = PackageManager .GET_META_DATA ;
1419- // it's useless to iterate over uninstalled packages if we don't support multi-profile apps
1420- if (G .supportDual ()) {
1421- pkgManagerFlags |= PackageManager .GET_UNINSTALLED_PACKAGES ;
1422- }
1418+ int pkgManagerFlags = PackageManager .GET_META_DATA | PackageManager .GET_UNINSTALLED_PACKAGES ;
14231419 PackageManager pkgmanager = ctx .getPackageManager ();
1424- List <ApplicationInfo > installed = pkgmanager .getInstalledApplications (pkgManagerFlags );
14251420 SparseArray <PackageInfoData > syncMap = new SparseArray <>();
14261421 Editor edit = cachePrefs .edit ();
14271422 boolean changed = false ;
14281423 String name ;
14291424 String cachekey ;
14301425 String cacheLabel = "cache.label." ;
14311426 PackageInfoData app ;
1432- ApplicationInfo apinfo ;
14331427
14341428 Date install = new Date ();
14351429 install .setTime (System .currentTimeMillis () - (180000 ));
@@ -1440,48 +1434,57 @@ public static List<PackageInfoData> getApps(Context ctx, GetAppList appList) {
14401434 packagesForUser = getPackagesForUser (listOfUids );
14411435 }
14421436
1443- for (int i = 0 ; i < installed .size (); i ++) {
1444- //for (ApplicationInfo apinfo : installed) {
1437+ //List<ApplicationInfo> installed = pkgmanager.getInstalledApplications(pkgManagerFlags);
1438+ /*List<PkgInfo> pkginfos = new ArrayList();
1439+ for (ApplicationInfo apinfo : installed) {
1440+ List<Integer> uids = new ArrayList();
1441+ String label = pkgmanager.getApplicationLabel(apinfo).toString();
1442+ uids.add(apinfo.uid);
1443+ pkginfos.add(new PkgInfo(apinfo.packageName, label, uids, apinfo.sourceDir, (apinfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0));
1444+ }*/
1445+ List <PkgInfo > pkginfos = getPackagesShell (pkgmanager );
1446+
1447+ for (PkgInfo pkg : pkginfos ) {
1448+ Log .i (TAG , "Processing app info: " + pkg .packageName );
14451449 count = count + 1 ;
1446- apinfo = installed .get (i );
14471450
14481451 if (appList != null ) {
14491452 appList .doProgress (count );
14501453 }
14511454
14521455 boolean firstseen = false ;
1453- app = syncMap .get (apinfo .uid );
1456+ app = syncMap .get (pkg .uid );
14541457 // filter applications which are not allowed to access the Internet
1455- if (app == null && PackageManager .PERMISSION_GRANTED != pkgmanager .checkPermission (Manifest .permission .INTERNET , apinfo .packageName ) && !showAllApps ()) {
1458+ // dumpsys package check-permission <package> android.permission.INTERNET <uid>
1459+ // contrary to help text, package goes first!
1460+ if (app == null && PackageManager .PERMISSION_GRANTED != pkgmanager .checkPermission (Manifest .permission .INTERNET , pkg .packageName ) && !showAllApps ()) {
14561461 continue ;
14571462 }
14581463 // try to get the application label from our cache - getApplicationLabel() is horribly slow!!!!
1459- cachekey = cacheLabel + apinfo .packageName ;
1464+ cachekey = cacheLabel + pkg .packageName + Integer . toString ( pkg . uid ) ;
14601465 name = prefs .getString (cachekey , "" );
1461- if (name .length () == 0 || isRecentlyInstalled (apinfo .packageName )) {
1466+ if (name .length () == 0 || isRecentlyInstalled (pkg .packageName )) {
14621467 // get label and put on cache
1463- name = pkgmanager . getApplicationLabel ( apinfo ) .toString ();
1468+ name = pkg . packageLabel + " / user " + Integer .toString (pkg . user_id );
14641469 edit .putString (cachekey , name );
14651470 changed = true ;
14661471 firstseen = true ;
14671472 }
14681473 if (app == null ) {
14691474 app = new PackageInfoData ();
1470- app .uid = apinfo .uid ;
1471- app .installTime = new File (apinfo .sourceDir ).lastModified ();
1475+ app .uid = pkg .uid ;
1476+ app .installTime = new File (pkg .sourceDir ).lastModified ();
14721477 app .names = new ArrayList <String >();
14731478 app .names .add (name );
1474- app .appinfo = apinfo ;
1475- if (app .appinfo != null && (app .appinfo .flags & ApplicationInfo .FLAG_SYSTEM ) == 0 ) {
1479+ if (!pkg .isSystem ) {
14761480 //user app
14771481 app .appType = 1 ;
14781482 } else {
14791483 //system app
14801484 app .appType = 0 ;
14811485 }
1482- app .pkgName = apinfo .packageName ;
1483- if ((apinfo .flags & ApplicationInfo .FLAG_INSTALLED ) != 0 )
1484- syncMap .put (apinfo .uid , app );
1486+ app .pkgName = pkg .packageName ;
1487+ syncMap .put (app .uid , app );
14851488 } else {
14861489 app .names .add (name );
14871490 }
@@ -1509,12 +1512,12 @@ public static List<PackageInfoData> getApps(Context ctx, GetAppList appList) {
15091512 if (G .enableTor () && !app .selected_tor && Collections .binarySearch (selected_tor , app .uid ) >= 0 ) {
15101513 app .selected_tor = true ;
15111514 }
1512- if (G .supportDual ()) {
1515+ /* if (G.supportDual()) {
15131516 checkPartOfMultiUser(apinfo, name, listOfUids, packagesForUser, multiUserAppsMap);
1514- }
1517+ }*/
15151518 }
15161519
1517- if (G .supportDual ()) {
1520+ /* if (G.supportDual()) {
15181521 //run through multi user map
15191522 for (int i = 0; i < multiUserAppsMap.size(); i++) {
15201523 app = multiUserAppsMap.valueAt(i);
@@ -1541,7 +1544,7 @@ public static List<PackageInfoData> getApps(Context ctx, GetAppList appList) {
15411544 }
15421545 syncMap.put(app.uid, app);
15431546 }
1544- }
1547+ }*/
15451548
15461549 List <PackageInfoData > specialData = getSpecialData ();
15471550
@@ -1636,7 +1639,7 @@ public static List<PackageInfoData> getSpecialData() {
16361639 return specialData ;
16371640 }
16381641
1639- private static void checkPartOfMultiUser (ApplicationInfo apinfo , String name , List <Integer > uid1 , HashMap <Integer ,String > pkgs , SparseArray <PackageInfoData > syncMap ) {
1642+ /* private static void checkPartOfMultiUser(ApplicationInfo apinfo, String name, List<Integer> uid1, HashMap<Integer,String> pkgs, SparseArray<PackageInfoData> syncMap) {
16401643 try {
16411644 for (Integer integer : uid1) {
16421645 int appUid = Integer.parseInt(integer + "" + apinfo.uid + "");
@@ -1666,7 +1669,7 @@ private static void checkPartOfMultiUser(ApplicationInfo apinfo, String name, Li
16661669 } catch (Exception e) {
16671670 Log.e(TAG, e.getMessage(), e);
16681671 }
1669- }
1672+ }*/
16701673
16711674 private static boolean packagesExistForUserUid (HashMap <Integer ,String > pkgs , int appUid ) {
16721675 if (pkgs .containsKey (appUid )){
@@ -1694,6 +1697,52 @@ public static HashMap<Integer, String> getPackagesForUser(List<Integer> userProf
16941697 return listApps .size () > 0 ? listApps : null ;
16951698 }
16961699
1700+ private static final Pattern pmfU = Pattern .compile ("package:(.*)=(.*?) uid:(.*)" , Pattern .MULTILINE );
1701+
1702+ public static List <PkgInfo > pkgInfoFromPm (PackageManager mgr , String item , boolean isSystem ) {
1703+ List <PkgInfo > infos = new ArrayList ();
1704+ Matcher matcher = pmfU .matcher (item );
1705+ if (matcher .find () && matcher .groupCount () > 0 ) {
1706+ String sourceDir = matcher .group (1 );
1707+ String packageName = matcher .group (2 );
1708+ String packageLabel = null ;
1709+ try {
1710+ ApplicationInfo info = mgr .getApplicationInfo (packageName , PackageManager .GET_UNINSTALLED_PACKAGES );
1711+ packageLabel = mgr .getApplicationLabel (info ).toString ();
1712+ } catch (NameNotFoundException e ) {
1713+ // test later for null
1714+ }
1715+ String [] uids = matcher .group (3 ).split ("," );
1716+ for (String uid : uids ) {
1717+ int uidi = Integer .parseInt (uid );
1718+ int user = uidi / 100000 ;
1719+ infos .add (new PkgInfo (packageName , (packageLabel == null )? packageName : packageLabel , uidi , user , sourceDir , isSystem ));
1720+ }
1721+ } else {
1722+ Log .i (TAG , "could not parse pm output: " + item );
1723+ }
1724+ return infos ;
1725+ }
1726+
1727+ public static List <PkgInfo > getPackagesShell (PackageManager mgr ) {
1728+ List <PkgInfo > pkginfos = new ArrayList ();
1729+ Shell .Result result ;
1730+ List <String > out ;
1731+ // user packages
1732+ result = Shell .cmd ("pm list packages -f -U -3" ).exec ();
1733+ out = result .getOut ();
1734+ for (String item : out ) {
1735+ pkginfos .addAll (pkgInfoFromPm (mgr , item , false ));
1736+ }
1737+ // system packages
1738+ result = Shell .cmd ("pm list packages -f -U -s" ).exec ();
1739+ out = result .getOut ();
1740+ for (String item : out ) {
1741+ pkginfos .addAll (pkgInfoFromPm (mgr , item , true ));
1742+ }
1743+ return pkginfos ;
1744+ }
1745+
16971746 private static boolean isRecentlyInstalled (String packageName ) {
16981747 boolean isRecent = false ;
16991748 if (recentlyInstalled != null && recentlyInstalled .contains (packageName )) {
@@ -2755,7 +2804,7 @@ public static boolean loadSharedPreferencesFromFile(Context ctx, StringBuilder b
27552804 public static void probeLogTarget (final Context ctx ) {
27562805
27572806 }
2758-
2807+
27592808 @ SuppressLint ("InlinedApi" )
27602809 public static void showInstalledAppDetails (Context context , String packageName ) {
27612810 final String SCHEME = "package" ;
@@ -3244,6 +3293,23 @@ protected Integer doInBackground(Object... params) {
32443293
32453294 }
32463295
3296+ public static final class PkgInfo {
3297+ public String packageName ;
3298+ public String packageLabel ;
3299+ public int uid ; // uid for the app
3300+ public int user_id ; // android user_id for the user
3301+ public String sourceDir ;
3302+ public boolean isSystem ;
3303+ public PkgInfo (String packageName , String packageLabel , int uid , int user_id , String sourceDir , boolean isSystem ) {
3304+ this .packageName = packageName ;
3305+ this .packageLabel = packageLabel ;
3306+ this .uid = uid ;
3307+ this .user_id = user_id ;
3308+ this .sourceDir = sourceDir ;
3309+ this .isSystem = isSystem ;
3310+ }
3311+ }
3312+
32473313 /**
32483314 * Small structure to hold an application info
32493315 */
@@ -3263,7 +3329,7 @@ public static final class PackageInfoData {
32633329 public String pkgName ;
32643330
32653331 /**
3266- * Application Type
3332+ * Application Type. 0 for system, 1 for user, 2 for core.
32673333 */
32683334 public int appType ;
32693335
@@ -3299,10 +3365,6 @@ public static final class PackageInfoData {
32993365 * toString cache
33003366 */
33013367 public String tostr ;
3302- /**
3303- * application info
3304- */
3305- public ApplicationInfo appinfo ;
33063368 /**
33073369 * cached application icon
33083370 */
@@ -3350,9 +3412,6 @@ public boolean equals(Object o) {
33503412 @ Override
33513413 public int hashCode () {
33523414 int result = 17 ;
3353- if (appinfo != null ) {
3354- result = 31 * result + appinfo .hashCode ();
3355- }
33563415 result = 31 * result + uid ;
33573416 result = 31 * result + pkgName .hashCode ();
33583417 return result ;
@@ -3379,13 +3438,12 @@ public String toString() {
33793438 public String toStringWithUID () {
33803439 if (tostr == null ) {
33813440 StringBuilder s = new StringBuilder ();
3382- s .append ("[ " );
3383- s .append (uid );
3384- s .append (" ] " );
33853441 for (int i = 0 ; i < names .size (); i ++) {
33863442 if (i != 0 ) s .append (", " );
33873443 s .append (names .get (i ));
33883444 }
3445+ s .append (" / " );
3446+ s .append (uid );
33893447 s .append ("\n " );
33903448 tostr = s .toString ();
33913449 }
0 commit comments