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 5c1724b1d..8592196d0 100644 --- a/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl +++ b/app/src/main/aidl/org/fdroid/fdroid/privileged/IPrivilegedService.aidl @@ -63,4 +63,6 @@ interface IPrivilegedService { */ oneway void deletePackage(in String packageName, in int flags, in IPrivilegedCallback callback); + List getInstalledPackages(in int flags); + } \ No newline at end of file diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java index d3113392e..8f60f111d 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java @@ -1,23 +1,25 @@ package org.fdroid.fdroid.data; +import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build; +import android.os.IBinder; import android.os.Process; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.JobIntentService; +import android.os.RemoteException; import android.util.Log; + import org.acra.ACRA; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.InstalledAppTable; -import rx.functions.Action1; -import rx.schedulers.Schedulers; -import rx.subjects.PublishSubject; +import org.fdroid.fdroid.installer.PrivilegedInstaller; +import org.fdroid.fdroid.privileged.IPrivilegedService; import java.io.File; import java.io.FilenameFilter; @@ -27,6 +29,13 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.JobIntentService; +import rx.functions.Action1; +import rx.schedulers.Schedulers; +import rx.subjects.PublishSubject; + /** * Handles all updates to {@link InstalledAppProvider}, whether checking the contents * versus what Android says is installed, or processing {@link Intent}s that come @@ -48,7 +57,6 @@ import java.util.concurrent.TimeUnit; * process was underway, e.g. uninstalling via {@code adb}, updates via Google * Play, Yalp, etc. */ -@SuppressWarnings("LineLength") public class InstalledAppProviderService extends JobIntentService { private static final String TAG = "InstalledAppProviderSer"; @@ -174,12 +182,45 @@ public class InstalledAppProviderService extends JobIntentService { * * @see cachedInfo = InstalledAppProvider.Helper.lastUpdateTimes(context); - List packageInfoList = context.getPackageManager() - .getInstalledPackages(PackageManager.GET_SIGNATURES); + if (Build.VERSION.SDK_INT >= 29 && + PrivilegedInstaller.isExtensionInstalledCorrectly(context) == + PrivilegedInstaller.IS_EXTENSION_INSTALLED_YES) { + ServiceConnection mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IPrivilegedService privService = IPrivilegedService.Stub.asInterface(service); + List packageInfoList = null; + try { + packageInfoList = privService.getInstalledPackages(PackageManager.GET_SIGNATURES); + } catch (RemoteException e) { + e.printStackTrace(); + } + compareToPackageManager(context, packageInfoList); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + // Nothing to tear down from onServiceConnected + } + }; + + Intent serviceIntent = new Intent(PrivilegedInstaller.PRIVILEGED_EXTENSION_SERVICE_INTENT); + serviceIntent.setPackage(PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME); + context.getApplicationContext().bindService(serviceIntent, mServiceConnection, + Context.BIND_AUTO_CREATE); + } else { + compareToPackageManager(context, null); + } + } + + private static void compareToPackageManager(Context context, List packageInfoList) { + if (packageInfoList == null || packageInfoList.isEmpty()) { + packageInfoList = context.getPackageManager().getInstalledPackages(PackageManager.GET_SIGNATURES); + } + Map cachedInfo = InstalledAppProvider.Helper.lastUpdateTimes(context); Collections.sort(packageInfoList, new Comparator() { @Override public int compare(PackageInfo o1, PackageInfo o2) { diff --git a/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java index 47e26c817..a60c804d4 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java @@ -66,7 +66,7 @@ public class PrivilegedInstaller extends Installer { private static final String TAG = "PrivilegedInstaller"; - private static final String PRIVILEGED_EXTENSION_SERVICE_INTENT + public static final String PRIVILEGED_EXTENSION_SERVICE_INTENT = "org.fdroid.fdroid.privileged.IPrivilegedService"; public static final String PRIVILEGED_EXTENSION_PACKAGE_NAME = BuildConfig.PRIVILEGED_EXTENSION_PACKAGE_NAME;