[app] Add support for IPFS CID downloading

This uses IndexFile objects instead of String file names everywhere. The general advantage of that is that we can now pass the hash and the file size to the downloader. For index v2 the hash can then get validated while downloading.
This commit is contained in:
Torsten Grote
2022-09-01 15:45:57 -03:00
committed by Hans-Christoph Steiner
parent 23966e4a09
commit fb5b169e54
26 changed files with 273 additions and 306 deletions

View File

@@ -20,6 +20,7 @@
package org.fdroid.fdroid;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.index.v2.FileV1;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -133,7 +134,7 @@ public class RepoUrlsTest {
public void testApkUrls() {
testReposWithFile(APK_NAME, tr -> {
Apk apk = new Apk();
apk.apkName = APK_NAME;
apk.apkFile = new FileV1(APK_NAME, "hash", null, null);
apk.versionCode = 1;
apk.repoAddress = tr.repoUrl;
apk.canonicalRepoAddress = tr.repoUrl;

View File

@@ -2,6 +2,7 @@ package org.fdroid.fdroid;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
import org.fdroid.index.v2.FileV1;
import java.io.File;
import java.io.FileOutputStream;
@@ -41,20 +42,19 @@ public class TestUtils {
}
}
public static Apk getApk(long appId, int versionCode) {
return getApk(appId, versionCode, "signature", null);
public static Apk getApk(int versionCode) {
return getApk(versionCode, "signature", null);
}
public static Apk getApk(long appId, int versionCode, String signature, String releaseChannel) {
public static Apk getApk(int versionCode, String signature, String releaseChannel) {
Apk apk = new Apk();
apk.appId = appId;
apk.repoAddress = "http://www.example.com/fdroid/repo";
apk.canonicalRepoAddress = "http://www.example.com/fdroid/repo";
apk.versionCode = versionCode;
apk.repoId = 1;
apk.versionName = "The good one";
apk.hash = "11111111aaaaaaaa";
apk.apkName = "Test Apk";
apk.apkFile = new FileV1("Test Apk", "hash", null, null);
apk.size = 10000;
apk.compatible = true;
apk.sig = signature;

View File

@@ -7,6 +7,7 @@ import android.webkit.MimeTypeMap;
import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.installer.ApkCache;
import org.fdroid.fdroid.nearby.PublicSourceDirProvider;
import org.fdroid.index.v2.FileV1;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -17,6 +18,7 @@ import org.robolectric.shadows.ShadowMimeTypeMap;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import androidx.test.core.app.ApplicationProvider;
@@ -41,7 +43,7 @@ public class ApkTest {
@Test(expected = IllegalStateException.class)
public void testGetMediaInstallPathWithApk() {
Apk apk = new Apk();
apk.apkName = "test.apk";
apk.apkFile = new FileV1("test.apk", "hash", null, null);
apk.repoAddress = "https://example.com/fdroid/repo";
apk.canonicalRepoAddress = "https://example.com/fdroid/repo";
assertTrue(apk.isApk());
@@ -51,7 +53,7 @@ public class ApkTest {
@Test
public void testGetMediaInstallPathWithOta() throws IOException {
Apk apk = new Apk();
apk.apkName = "org.fdroid.fdroid.privileged.ota_2110.zip";
apk.apkFile = new FileV1("org.fdroid.fdroid.privileged.ota_2110.zip", "hash", null, null);
apk.repoAddress = "https://example.com/fdroid/repo";
apk.canonicalRepoAddress = "https://example.com/fdroid/repo";
assertFalse(apk.isApk());
@@ -63,7 +65,7 @@ public class ApkTest {
@Test
public void testGetMediaInstallPathWithObf() {
Apk apk = new Apk();
apk.apkName = "Norway_bouvet_europe_2.obf";
apk.apkFile = new FileV1("Norway_bouvet_europe_2.obf", "hash", null, null);
apk.repoAddress = "https://example.com/fdroid/repo";
apk.canonicalRepoAddress = "https://example.com/fdroid/repo";
assertFalse(apk.isApk());
@@ -74,7 +76,7 @@ public class ApkTest {
@Test
public void testGetMediaInstallPathWithObfZip() throws IOException {
Apk apk = new Apk();
apk.apkName = "Norway_bouvet_europe_2.obf.zip";
apk.apkFile = new FileV1("Norway_bouvet_europe_2.obf.zip", "hash", null, null);
apk.repoAddress = "https://example.com/fdroid/repo";
apk.canonicalRepoAddress = "https://example.com/fdroid/repo";
assertFalse(apk.isApk());
@@ -84,7 +86,8 @@ public class ApkTest {
}
private void copyResourceFileToCache(Apk apk) throws IOException {
FileUtils.copyInputStreamToFile(getClass().getClassLoader().getResource(apk.apkName).openStream(),
URL res = getClass().getClassLoader().getResource(apk.apkFile.getName());
FileUtils.copyInputStreamToFile(res.openStream(),
ApkCache.getApkDownloadPath(context, apk.getCanonicalUrl()));
}
}

View File

@@ -38,9 +38,9 @@ public class SuggestedVersionTest {
App singleApp = TestUtils.getApp();
singleApp.installedVersionCode = 1;
singleApp.installedSig = TestUtils.FDROID_SIG;
Apk apk1 = TestUtils.getApk(singleApp.getId(), 1, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk2 = TestUtils.getApk(singleApp.getId(), 2, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk3 = TestUtils.getApk(singleApp.getId(), 3, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_BETA);
Apk apk1 = TestUtils.getApk(1, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk2 = TestUtils.getApk(2, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk3 = TestUtils.getApk(3, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_BETA);
List<Apk> apks = new ArrayList<>();
apks.add(apk3);
apks.add(apk2);
@@ -57,11 +57,11 @@ public class SuggestedVersionTest {
App singleApp = TestUtils.getApp();
singleApp.installedVersionCode = 0;
Apk apk1 = TestUtils.getApk(singleApp.getId(), 1, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk2 = TestUtils.getApk(singleApp.getId(), 2, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk3 = TestUtils.getApk(singleApp.getId(), 3, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk4 = TestUtils.getApk(singleApp.getId(), 4, TestUtils.UPSTREAM_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk5 = TestUtils.getApk(singleApp.getId(), 5, TestUtils.UPSTREAM_SIG, Apk.RELEASE_CHANNEL_BETA);
Apk apk1 = TestUtils.getApk(1, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk2 = TestUtils.getApk(2, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk3 = TestUtils.getApk(3, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk4 = TestUtils.getApk(4, TestUtils.UPSTREAM_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk5 = TestUtils.getApk(5, TestUtils.UPSTREAM_SIG, Apk.RELEASE_CHANNEL_BETA);
List<Apk> apks = new ArrayList<>();
apks.add(apk5);
apks.add(apk4);
@@ -80,8 +80,8 @@ public class SuggestedVersionTest {
assertSuggested(singleApp, apks, 3, Apk.RELEASE_CHANNEL_STABLE);
// This adds the "suggestedVersionCode" version of the app, but signed by f-droid.
Apk apk4f = TestUtils.getApk(singleApp.getId(), 4, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk5f = TestUtils.getApk(singleApp.getId(), 5, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_BETA);
Apk apk4f = TestUtils.getApk(4, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_STABLE);
Apk apk5f = TestUtils.getApk(5, TestUtils.FDROID_SIG, Apk.RELEASE_CHANNEL_BETA);
apks.clear();
apks.add(apk5);
apks.add(apk5f);

View File

@@ -4,6 +4,7 @@ import android.content.ContextWrapper;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.index.v2.FileV1;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -17,7 +18,6 @@ import static org.junit.Assert.assertFalse;
@RunWith(RobolectricTestRunner.class)
public class FileInstallerTest {
public static final String TAG = "FileInstallerTest";
private ContextWrapper context;
@@ -31,7 +31,7 @@ public class FileInstallerTest {
@Test
public void testInstallOtaZip() {
Apk apk = new Apk();
apk.apkName = "org.fdroid.fdroid.privileged.ota_2010.zip";
apk.apkFile = new FileV1("org.fdroid.fdroid.privileged.ota_2010.zip", "hash", null, null);
apk.packageName = "org.fdroid.fdroid.privileged.ota";
apk.versionCode = 2010;
assertFalse(apk.isApk());

View File

@@ -4,6 +4,7 @@ import android.content.ContextWrapper;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.index.v2.FileV1;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,7 +29,7 @@ public class InstallerFactoryTest {
public void testApkInstallerInstance() {
for (String filename : new String[]{"test.apk", "A.APK", "b.ApK"}) {
Apk apk = new Apk();
apk.apkName = filename;
apk.apkFile = new FileV1(filename, "hash", null, null);
apk.packageName = "test";
Installer installer = InstallerFactory.create(context, apk);
assertEquals(filename + " should use a DefaultInstaller",
@@ -41,7 +42,7 @@ public class InstallerFactoryTest {
public void testFileInstallerInstance() {
for (String filename : new String[]{"org.fdroid.fdroid.privileged.ota_2110.zip", "test.ZIP"}) {
Apk apk = new Apk();
apk.apkName = filename;
apk.apkFile = new FileV1(filename, "hash", null, null);
apk.packageName = "cafe0088";
Installer installer = InstallerFactory.create(context, apk);
assertEquals("should be a FileInstaller",

View File

@@ -17,6 +17,7 @@ import org.fdroid.fdroid.R;
import org.fdroid.fdroid.TestUtils;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
import org.fdroid.index.v2.FileV2;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,7 +58,9 @@ public class AppDetailsAdapterTest {
@Test
public void appWithScreenshots() {
App app = TestUtils.getApp();
app.phoneScreenshots = new String[]{"screenshot1.png", "screenshot2.png"};
app.phoneScreenshots = new ArrayList<>(2);
app.phoneScreenshots.add(FileV2.fromPath("screenshot1.png"));
app.phoneScreenshots.add(FileV2.fromPath("screenshot2.png"));
AppDetailsRecyclerViewAdapter adapter = new AppDetailsRecyclerViewAdapter(context, app, dummyCallbacks);
adapter.updateItems(app, Collections.emptyList(), appPrefs);
@@ -71,9 +74,9 @@ public class AppDetailsAdapterTest {
App app = TestUtils.getApp();
app.preferredSigner = "eaa1d713b9c2a0475234a86d6539f910";
List<Apk> apks = new ArrayList<>();
apks.add(TestUtils.getApk(app.getId(), 1));
apks.add(TestUtils.getApk(app.getId(), 2));
apks.add(TestUtils.getApk(app.getId(), 3));
apks.add(TestUtils.getApk(1));
apks.add(TestUtils.getApk(2));
apks.add(TestUtils.getApk(3));
app.installedApk = apks.get(0);
AppDetailsRecyclerViewAdapter adapter = new AppDetailsRecyclerViewAdapter(context, app, dummyCallbacks);