use of org.fdroid.fdroid.data.App in project fdroidclient by f-droid.
the class UpdatesAdapter method onCanUpdateLoadFinished.
private void onCanUpdateLoadFinished(Cursor cursor) {
updateableApps.clear();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
updateableApps.add(new UpdateableApp(activity, new App(cursor)));
cursor.moveToNext();
}
}
use of org.fdroid.fdroid.data.App in project fdroidclient by f-droid.
the class LatestAdapter method onBindViewHolder.
@Override
public void onBindViewHolder(@NonNull AppCardController holder, int position) {
cursor.moveToPosition(position);
final App app = new App(cursor);
holder.bindApp(app);
}
use of org.fdroid.fdroid.data.App in project fdroidclient by f-droid.
the class LocalRepoManager method writeIndexPage.
public void writeIndexPage(String repoAddress) {
final String fdroidClientURL = writeFdroidApkToWebroot();
try {
File indexHtml = new File(webRoot, "index.html");
BufferedReader in = new BufferedReader(new InputStreamReader(assetManager.open("index.template.html"), "UTF-8"));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexHtml)));
StringBuilder builder = new StringBuilder();
for (App app : apps.values()) {
builder.append("<li><a href=\"/fdroid/repo/").append(app.installedApk.apkName).append("\"><img width=\"32\" height=\"32\" src=\"/fdroid/repo/icons/").append(app.packageName).append("_").append(app.installedApk.versionCode).append(".png\">").append(app.name).append("</a></li>\n");
}
String line;
while ((line = in.readLine()) != null) {
line = line.replaceAll("\\{\\{REPO_URL\\}\\}", repoAddress);
line = line.replaceAll("\\{\\{CLIENT_URL\\}\\}", fdroidClientURL);
line = line.replaceAll("\\{\\{APP_LIST\\}\\}", builder.toString());
out.write(line);
}
in.close();
out.close();
for (final String file : WEB_ROOT_ASSET_FILES) {
InputStream assetIn = assetManager.open(file);
OutputStream assetOut = new FileOutputStream(new File(webRoot, file));
Utils.copy(assetIn, assetOut);
assetIn.close();
assetOut.close();
}
// make symlinks/copies in each subdir of the repo to make sure that
// the user will always find the bootstrap page.
symlinkEntireWebRootElsewhere("../", fdroidDir);
symlinkEntireWebRootElsewhere("../../", repoDir);
// add in /FDROID/REPO to support bad QR Scanner apps
attemptToMkdir(fdroidDirCaps);
attemptToMkdir(repoDirCaps);
symlinkEntireWebRootElsewhere("../", fdroidDirCaps);
symlinkEntireWebRootElsewhere("../../", repoDirCaps);
} catch (IOException e) {
Log.e(TAG, "Error writing local repo index", e);
}
}
use of org.fdroid.fdroid.data.App in project fdroidclient by f-droid.
the class LocalRepoManager method addApp.
public void addApp(Context context, String packageName) {
App app = null;
try {
InstalledApp installedApp = InstalledAppProvider.Helper.findByPackageName(context, packageName);
app = App.getInstance(context, pm, installedApp, packageName);
if (app == null || !app.isValid()) {
return;
}
} catch (PackageManager.NameNotFoundException | CertificateEncodingException | IOException e) {
Log.e(TAG, "Error adding app to local repo", e);
return;
}
Utils.debugLog(TAG, "apps.put: " + packageName);
apps.put(packageName, app);
}
use of org.fdroid.fdroid.data.App in project fdroidclient by f-droid.
the class SwapRepoEmulatorTest method testSwap.
/**
* @see org.fdroid.fdroid.nearby.WifiStateChangeService.WifiInfoThread#run()
*/
@Ignore
@Test
public void testSwap() throws IOException, LocalRepoKeyStore.InitException, IndexUpdater.UpdateException, InterruptedException {
Looper.prepare();
LocalHTTPD localHttpd = null;
try {
Log.i(TAG, "REPO: " + FDroidApp.repo);
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
Preferences.setupForTests(context);
FDroidApp.initWifiSettings();
assertNull(FDroidApp.repo.address);
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
@Override
public void run() {
while (FDroidApp.repo.address == null) {
try {
Log.i(TAG, "Waiting for IP address... " + FDroidApp.repo.address);
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
}
latch.countDown();
}
}.start();
latch.await(10, TimeUnit.MINUTES);
assertNotNull(FDroidApp.repo.address);
LocalRepoService.runProcess(context, new String[] { context.getPackageName() });
Log.i(TAG, "REPO: " + FDroidApp.repo);
File indexJarFile = LocalRepoManager.get(context).getIndexJar();
assertTrue(indexJarFile.isFile());
localHttpd = new LocalHTTPD(context, null, FDroidApp.port, LocalRepoManager.get(context).getWebRoot(), false);
localHttpd.start();
// give the server some tine to start.
Thread.sleep(100);
assertTrue(localHttpd.isAlive());
LocalRepoKeyStore localRepoKeyStore = LocalRepoKeyStore.get(context);
Certificate localCert = localRepoKeyStore.getCertificate();
String signingCert = Hasher.hex(localCert);
assertFalse(TextUtils.isEmpty(signingCert));
assertFalse(TextUtils.isEmpty(Utils.calcFingerprint(localCert)));
Repo repoToDelete = RepoProvider.Helper.findByAddress(context, FDroidApp.repo.address);
while (repoToDelete != null) {
Log.d(TAG, "Removing old test swap repo matching this one: " + repoToDelete.address);
RepoProvider.Helper.remove(context, repoToDelete.getId());
repoToDelete = RepoProvider.Helper.findByAddress(context, FDroidApp.repo.address);
}
ContentValues values = new ContentValues(4);
values.put(Schema.RepoTable.Cols.SIGNING_CERT, signingCert);
values.put(Schema.RepoTable.Cols.ADDRESS, FDroidApp.repo.address);
values.put(Schema.RepoTable.Cols.NAME, FDroidApp.repo.name);
values.put(Schema.RepoTable.Cols.IS_SWAP, true);
final String lastEtag = UUID.randomUUID().toString();
values.put(Schema.RepoTable.Cols.LAST_ETAG, lastEtag);
RepoProvider.Helper.insert(context, values);
Repo repo = RepoProvider.Helper.findByAddress(context, FDroidApp.repo.address);
assertTrue(repo.isSwap);
assertNotEquals(-1, repo.getId());
assertTrue(repo.name.startsWith(FDroidApp.repo.name));
assertEquals(lastEtag, repo.lastetag);
assertNull(repo.lastUpdated);
assertTrue(isPortInUse(FDroidApp.ipAddressString, FDroidApp.port));
Thread.sleep(100);
IndexUpdater updater = new IndexUpdater(context, repo);
updater.update();
assertTrue(updater.hasChanged());
repo = RepoProvider.Helper.findByAddress(context, FDroidApp.repo.address);
final Date lastUpdated = repo.lastUpdated;
assertTrue("repo lastUpdated should be updated", new Date(2019, 5, 13).compareTo(repo.lastUpdated) > 0);
App app = AppProvider.Helper.findSpecificApp(context.getContentResolver(), context.getPackageName(), repo.getId());
assertEquals(context.getPackageName(), app.packageName);
List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, Schema.ApkTable.Cols.ALL);
assertEquals(1, apks.size());
for (Apk apk : apks) {
Log.i(TAG, "Apk: " + apk);
assertEquals(context.getPackageName(), apk.packageName);
assertEquals(BuildConfig.VERSION_NAME, apk.versionName);
assertEquals(BuildConfig.VERSION_CODE, apk.versionCode);
assertEquals(app.repoId, apk.repoId);
}
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(mainIntent, 0);
HashSet<String> packageNames = new HashSet<>();
for (ResolveInfo resolveInfo : resolveInfoList) {
if (!isSystemPackage(resolveInfo)) {
Log.i(TAG, "resolveInfo: " + resolveInfo);
packageNames.add(resolveInfo.activityInfo.packageName);
}
}
LocalRepoService.runProcess(context, packageNames.toArray(new String[0]));
updater = new IndexUpdater(context, repo);
updater.update();
assertTrue(updater.hasChanged());
assertTrue("repo lastUpdated should be updated", lastUpdated.compareTo(repo.lastUpdated) < 0);
for (String packageName : packageNames) {
assertNotNull(ApkProvider.Helper.findByPackageName(context, packageName));
}
} finally {
if (localHttpd != null) {
localHttpd.stop();
}
}
if (localHttpd != null) {
assertFalse(localHttpd.isAlive());
}
}
Aggregations