Merge branch 'master' into 'master'

Add getInstalledPackages API with MATCH_STATIC_SHARED_LIBRARIES flag

See merge request fdroid/privileged-extension!58
diff --git a/app/src/androidTest/java/org/fdroid/fdroid/privileged/PrivilegedServiceTest.java b/app/src/androidTest/java/org/fdroid/fdroid/privileged/PrivilegedServiceTest.java
new file mode 100644
index 0000000..29ca748
--- /dev/null
+++ b/app/src/androidTest/java/org/fdroid/fdroid/privileged/PrivilegedServiceTest.java
@@ -0,0 +1,26 @@
+package org.fdroid.fdroid.privileged;
+
+import android.os.Build;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeTrue;
+
+@RunWith(AndroidJUnit4.class)
+public class PrivilegedServiceTest {
+    @Test
+    public void testGetMatchStaticSharedLibraries() {
+        Integer flag = PrivilegedService.getMatchStaticSharedLibraries();
+        if (Build.VERSION.SDK_INT < 29) {
+            assertEquals(null, flag);
+        } else {
+            assertNotEquals(null, flag);
+            // Must match PackageManager.MATCH_STATIC_SHARED_LIBRARIES
+            assumeTrue(flag == 0x04000000);
+        }
+    }
+}
diff --git a/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl b/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl
index 4fb564d..ca2524a 100644
--- a/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl
+++ b/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl
@@ -60,4 +60,6 @@
      */
     oneway void deletePackage(in String packageName, in int flags, in IPrivilegedCallback callback);
 
+    List<PackageInfo> getInstalledPackages(in int flags);
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java b/app/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
index 442255f..bbc83ec 100644
--- a/app/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
+++ b/app/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageInstallObserver;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.net.Uri;
@@ -41,6 +42,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Method;
+import java.util.List;
 
 /**
  * This service provides an API via AIDL IPC for the main F-Droid app to install/delete packages.
@@ -244,8 +246,34 @@
                 deletePackageImpl(packageName, flags, callback);
             }
         }
+
+        @Override
+        public List<PackageInfo> getInstalledPackages(int flags) {
+            if (Build.VERSION.SDK_INT >= 29) {
+                Integer matchStaticSharedLibraries = getMatchStaticSharedLibraries();
+                if (matchStaticSharedLibraries != null) {
+                    flags |= matchStaticSharedLibraries;
+                }
+            }
+            return getPackageManager().getInstalledPackages(flags);
+        }
     };
 
+    /**
+     * Get private constant.
+     *
+     * @see <a href="https://github.com/aosp-mirror/platform_frameworks_base/blob/android-11.0.0_r31/core/java/android/content/pm/PackageManager.java#L530">PackageManager.MATCH_STATIC_SHARED_LIBRARIES</a>
+     */
+    protected static Integer getMatchStaticSharedLibraries() {
+        try {
+            java.lang.reflect.Field field = PackageManager.class.getDeclaredField("MATCH_STATIC_SHARED_LIBRARIES");
+            return (Integer) field.get(null);
+        } catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
     @Override
     public IBinder onBind(Intent intent) {
         return binder;