purge CacheSwapAppsService in favor of InstalledAppProvider
The most expensive part of this whole process is calculating the hash of the whole APK. InstalledAppProvider already caches that, and the rest is OK to query. If any particular part of the query is expensive, it could also be moved to InstalledAppProviderService.
This commit is contained in:
parent
85410504da
commit
ea3b47f705
@ -77,9 +77,6 @@
|
||||
android:exported="false"/>
|
||||
<service android:name=".localrepo.SwapService"/>
|
||||
|
||||
<service
|
||||
android:name=".localrepo.CacheSwapAppsService"
|
||||
android:exported="false"/>
|
||||
<service
|
||||
android:name=".localrepo.LocalRepoService"
|
||||
android:exported="false"/>
|
||||
|
@ -1,85 +0,0 @@
|
||||
package org.fdroid.fdroid.localrepo;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
|
||||
/**
|
||||
* An {@link IntentService} subclass for generating cached info about the installed APKs
|
||||
* which are available for swapping. It does not cache system apps, since those are
|
||||
* rarely swapped. This is meant to start running when {@link SwapService} starts.
|
||||
* <p>
|
||||
* This could probably be replaced by {@link org.fdroid.fdroid.data.InstalledAppProvider}
|
||||
* if that contained all of the info to generate complete {@link App} and
|
||||
* {@link org.fdroid.fdroid.data.Apk} instances.
|
||||
*/
|
||||
public class CacheSwapAppsService extends IntentService {
|
||||
private static final String TAG = "CacheSwapAppsService";
|
||||
|
||||
private static final String ACTION_PARSE_APP = "org.fdroid.fdroid.localrepo.action.PARSE_APP";
|
||||
|
||||
public CacheSwapAppsService() {
|
||||
super("CacheSwapAppsService");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the locally installed APK for {@code packageName} and save its XML
|
||||
* to the APK XML cache.
|
||||
*/
|
||||
private static void parseApp(Context context, String packageName) {
|
||||
Intent intent = new Intent();
|
||||
intent.setData(Utils.getPackageUri(packageName));
|
||||
intent.setClass(context, CacheSwapAppsService.class);
|
||||
intent.setAction(ACTION_PARSE_APP);
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all of the locally installed APKs into a memory cache, starting
|
||||
* with the currently selected apps. APKs that are already parsed in the
|
||||
* {@code index.jar} file will be read from that file.
|
||||
*/
|
||||
public static void startCaching(Context context) {
|
||||
File indexJarFile = LocalRepoManager.get(context).getIndexJar();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
for (ApplicationInfo applicationInfo : pm.getInstalledApplications(0)) {
|
||||
if (applicationInfo.publicSourceDir.startsWith(FDroidApp.SYSTEM_DIR_NAME)) {
|
||||
continue;
|
||||
}
|
||||
if (!indexJarFile.exists()
|
||||
|| FileUtils.isFileNewer(new File(applicationInfo.sourceDir), indexJarFile)) {
|
||||
parseApp(context, applicationInfo.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST);
|
||||
if (intent == null || !ACTION_PARSE_APP.equals(intent.getAction())) {
|
||||
Utils.debugLog(TAG, "received bad Intent: " + intent);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
PackageManager pm = getPackageManager();
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
App app = App.getInstance(this, pm, packageName);
|
||||
if (app != null) {
|
||||
SwapService.putAppInCache(packageName, app);
|
||||
}
|
||||
} catch (CertificateEncodingException | IOException | PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -276,12 +276,10 @@ public final class LocalRepoManager {
|
||||
}
|
||||
|
||||
public void addApp(Context context, String packageName) {
|
||||
App app;
|
||||
App app = null;
|
||||
try {
|
||||
app = SwapService.getAppFromCache(packageName);
|
||||
if (app == null) {
|
||||
app = App.getInstance(context.getApplicationContext(), pm, packageName);
|
||||
}
|
||||
InstalledApp installedApp = InstalledAppProvider.Helper.findByPackageName(context, packageName);
|
||||
app = App.getInstance(context, pm, installedApp, packageName);
|
||||
if (app == null || !app.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.data.RepoProvider;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
@ -53,7 +52,6 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Central service which manages all of the different moving parts of swap which are required
|
||||
@ -74,11 +72,6 @@ public class SwapService extends Service {
|
||||
@NonNull
|
||||
private final Set<String> appsToSwap = new HashSet<>();
|
||||
|
||||
/**
|
||||
* A cache of parsed APKs from the file system.
|
||||
*/
|
||||
private static final ConcurrentHashMap<String, App> INSTALLED_APPS = new ConcurrentHashMap<>();
|
||||
|
||||
private static SharedPreferences swapPreferences;
|
||||
private static BluetoothAdapter bluetoothAdapter;
|
||||
private static WifiManager wifiManager;
|
||||
@ -88,14 +81,6 @@ public class SwapService extends Service {
|
||||
context.stopService(intent);
|
||||
}
|
||||
|
||||
static App getAppFromCache(String packageName) {
|
||||
return INSTALLED_APPS.get(packageName);
|
||||
}
|
||||
|
||||
static void putAppInCache(String packageName, @NonNull App app) {
|
||||
INSTALLED_APPS.put(packageName, app);
|
||||
}
|
||||
|
||||
// ==========================================================
|
||||
// Search for peers to swap
|
||||
// ==========================================================
|
||||
@ -447,8 +432,6 @@ public class SwapService extends Service {
|
||||
|
||||
deleteAllSwapRepos();
|
||||
|
||||
CacheSwapAppsService.startCaching(this);
|
||||
|
||||
swapPreferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
|
||||
|
||||
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
@ -385,13 +385,16 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
* exists.
|
||||
*/
|
||||
@Nullable
|
||||
public static App getInstance(Context context, PackageManager pm, String packageName)
|
||||
public static App getInstance(Context context, PackageManager pm, InstalledApp installedApp, String packageName)
|
||||
throws CertificateEncodingException, IOException, PackageManager.NameNotFoundException {
|
||||
App app = new App();
|
||||
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
|
||||
SanitizedFile apkFile = SanitizedFile.knownSanitized(packageInfo.applicationInfo.publicSourceDir);
|
||||
app.installedApk = new Apk();
|
||||
if (apkFile.canRead()) {
|
||||
if (installedApp != null) {
|
||||
app.installedApk.hashType = installedApp.getHashType();
|
||||
app.installedApk.hash = installedApp.getHash();
|
||||
} else if (apkFile.canRead()) {
|
||||
String hashType = "sha256";
|
||||
String hash = Utils.getBinaryHash(apkFile, hashType);
|
||||
if (TextUtils.isEmpty(hash)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user