diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..6e7cd433e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*.{kt, kts}] +max_line_length = 100 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9df689423..7d3c4aae1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,6 +34,7 @@ stages: - app/build/reports - app/build/outputs/*ml - app/build/outputs/apk + - build/reports expire_in: 1 week when: on_failure after_script: @@ -49,10 +50,11 @@ test_lint_pmd_checkstyle: - ./gradlew assemble # always report on lint errors to the build log - sed -i -e 's,textReport .*,textReport true,' app/build.gradle - - ./gradlew testFullDebugUnitTest || set_error + - ./gradlew testDebugUnitTest testFullDebugUnitTest || set_error - ./gradlew lint || set_error - ./gradlew pmd || set_error - ./gradlew checkstyle || set_error + - ./gradlew ktlintCheck || set_error - ./tools/check-format-strings.py || set_error - ./tools/check-fastlane-whitespace.py || set_error - ./tools/remove-unused-and-blank-translations.py || set_error diff --git a/app/build.gradle b/app/build.gradle index 774158d9f..1e89d91c2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -177,8 +177,8 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.1' implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.1' - implementation "com.github.bumptech.glide:glide:$glide_version" - annotationProcessor "com.github.bumptech.glide:compiler:$glide_version" + implementation "com.github.bumptech.glide:glide:4.12.0" + annotationProcessor "com.github.bumptech.glide:compiler:4.12.0" implementation 'org.bouncycastle:bcprov-jdk15on:1.65' fullImplementation 'org.bouncycastle:bcpkix-jdk15on:1.65' diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/SwapService.java b/app/src/full/java/org/fdroid/fdroid/nearby/SwapService.java index cc21725a2..56ee7e239 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/SwapService.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/SwapService.java @@ -26,7 +26,7 @@ import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.Schema; import org.fdroid.fdroid.nearby.peers.Peer; -import org.fdroid.download.Downloader; +import org.fdroid.fdroid.net.DownloaderService; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -392,9 +392,9 @@ public class SwapService extends Service { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .onErrorComplete(e -> { - Intent intent = new Intent(Downloader.ACTION_INTERRUPTED); + Intent intent = new Intent(DownloaderService.ACTION_INTERRUPTED); intent.setData(Uri.parse(repo.address)); - intent.putExtra(Downloader.EXTRA_ERROR_MESSAGE, e.getLocalizedMessage()); + intent.putExtra(DownloaderService.EXTRA_ERROR_MESSAGE, e.getLocalizedMessage()); LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent); return true; }) diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/SwapSuccessView.java b/app/src/full/java/org/fdroid/fdroid/nearby/SwapSuccessView.java index fba7d790f..f3573d650 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/SwapSuccessView.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/SwapSuccessView.java @@ -153,15 +153,15 @@ public class SwapSuccessView extends SwapView implements LoaderManager.LoaderCal @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { - case Downloader.ACTION_STARTED: + case DownloaderService.ACTION_STARTED: resetView(); break; - case Downloader.ACTION_PROGRESS: + case DownloaderService.ACTION_PROGRESS: if (progressView.getVisibility() != View.VISIBLE) { showProgress(); } - long read = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); - long total = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + long read = intent.getLongExtra(DownloaderService.EXTRA_BYTES_READ, 0); + long total = intent.getLongExtra(DownloaderService.EXTRA_TOTAL_BYTES, 0); if (total > 0) { progressView.setIndeterminate(false); progressView.setMax(100); @@ -170,17 +170,17 @@ public class SwapSuccessView extends SwapView implements LoaderManager.LoaderCal progressView.setIndeterminate(true); } break; - case Downloader.ACTION_COMPLETE: + case DownloaderService.ACTION_COMPLETE: localBroadcastManager.unregisterReceiver(this); resetView(); statusInstalled.setText(R.string.installing); statusInstalled.setVisibility(View.VISIBLE); btnInstall.setVisibility(View.GONE); break; - case Downloader.ACTION_INTERRUPTED: + case DownloaderService.ACTION_INTERRUPTED: localBroadcastManager.unregisterReceiver(this); - if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { - String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) + if (intent.hasExtra(DownloaderService.EXTRA_ERROR_MESSAGE)) { + String msg = intent.getStringExtra(DownloaderService.EXTRA_ERROR_MESSAGE) + " " + intent.getDataString(); Toast.makeText(context, R.string.download_error, Toast.LENGTH_SHORT).show(); Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java b/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java index 34fc24359..ff0881761 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java @@ -54,6 +54,7 @@ import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.nearby.peers.BluetoothPeer; import org.fdroid.fdroid.nearby.peers.Peer; import org.fdroid.fdroid.net.BluetoothDownloader; +import org.fdroid.fdroid.net.DownloaderService; import org.fdroid.fdroid.qr.CameraCharacteristicsChecker; import org.fdroid.fdroid.views.main.MainActivity; @@ -273,7 +274,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { localBroadcastManager = LocalBroadcastManager.getInstance(this); localBroadcastManager.registerReceiver(downloaderInterruptedReceiver, - new IntentFilter(Downloader.ACTION_INTERRUPTED)); + new IntentFilter(DownloaderService.ACTION_INTERRUPTED)); wifiManager = ContextCompat.getSystemService(getApplicationContext(), WifiManager.class); wifiApControl = WifiApControl.getInstance(this); @@ -1505,7 +1506,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { public void onReceive(Context context, Intent intent) { Repo repo = RepoProvider.Helper.findByUrl(context, intent.getData(), null); if (repo != null && repo.isSwap) { - setUpConnectingProgressText(intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE)); + setUpConnectingProgressText(intent.getStringExtra(DownloaderService.EXTRA_ERROR_MESSAGE)); } } }; diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index 6f35c73dc..879732afa 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -10,13 +10,13 @@ import android.content.pm.PackageManager; import android.os.Parcel; import android.os.Parcelable; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.installer.ErrorDialogActivity; import org.fdroid.fdroid.installer.InstallManagerService; +import org.fdroid.fdroid.net.DownloaderService; import org.fdroid.fdroid.views.AppDetailsActivity; import java.util.ArrayList; @@ -292,7 +292,7 @@ public final class AppUpdateStatusManager { private void notifyAdd(AppUpdateStatus entry) { if (!isBatchUpdating) { Intent broadcastIntent = new Intent(BROADCAST_APPSTATUS_ADDED); - broadcastIntent.putExtra(Downloader.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); + broadcastIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); broadcastIntent.putExtra(EXTRA_STATUS, entry.copy()); localBroadcastManager.sendBroadcast(broadcastIntent); } @@ -301,7 +301,7 @@ public final class AppUpdateStatusManager { private void notifyChange(AppUpdateStatus entry, boolean isStatusUpdate) { if (!isBatchUpdating) { Intent broadcastIntent = new Intent(BROADCAST_APPSTATUS_CHANGED); - broadcastIntent.putExtra(Downloader.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); + broadcastIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); broadcastIntent.putExtra(EXTRA_STATUS, entry.copy()); broadcastIntent.putExtra(EXTRA_IS_STATUS_UPDATE, isStatusUpdate); localBroadcastManager.sendBroadcast(broadcastIntent); @@ -311,7 +311,7 @@ public final class AppUpdateStatusManager { private void notifyRemove(AppUpdateStatus entry) { if (!isBatchUpdating) { Intent broadcastIntent = new Intent(BROADCAST_APPSTATUS_REMOVED); - broadcastIntent.putExtra(Downloader.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); + broadcastIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); broadcastIntent.putExtra(EXTRA_STATUS, entry.copy()); localBroadcastManager.sendBroadcast(broadcastIntent); } diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationBroadcastReceiver.java b/app/src/main/java/org/fdroid/fdroid/NotificationBroadcastReceiver.java index 0239daa22..74d1355c5 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationBroadcastReceiver.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationBroadcastReceiver.java @@ -4,7 +4,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import org.fdroid.download.Downloader; +import org.fdroid.fdroid.net.DownloaderService; /** * For security purposes we need to ensure that all Intent objects we give to a PendingIntent are @@ -16,7 +16,7 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { AppUpdateStatusManager manager = AppUpdateStatusManager.getInstance(context); - String canonicalUrl = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL); + String canonicalUrl = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL); switch (intent.getAction()) { case NotificationHelper.BROADCAST_NOTIFICATIONS_ALL_UPDATES_CLEARED: manager.clearAllUpdates(); diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java index 7257249ad..883a3d75d 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java @@ -30,8 +30,8 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.data.App; +import org.fdroid.fdroid.net.DownloaderService; import org.fdroid.fdroid.views.AppDetailsActivity; import org.fdroid.fdroid.views.main.MainActivity; @@ -114,14 +114,14 @@ public class NotificationHelper { case AppUpdateStatusManager.BROADCAST_APPSTATUS_ADDED: updateStatusLists(); createSummaryNotifications(); - url = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL); + url = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL); entry = appUpdateStatusManager.get(url); if (entry != null) { createNotification(entry); } break; case AppUpdateStatusManager.BROADCAST_APPSTATUS_CHANGED: - url = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL); + url = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL); entry = appUpdateStatusManager.get(url); updateStatusLists(); if (entry != null) { @@ -132,7 +132,7 @@ public class NotificationHelper { } break; case AppUpdateStatusManager.BROADCAST_APPSTATUS_REMOVED: - url = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL); + url = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL); notificationManager.cancel(url, NOTIFY_ID_INSTALLED); notificationManager.cancel(url, NOTIFY_ID_UPDATES); updateStatusLists(); @@ -365,7 +365,7 @@ public class NotificationHelper { } Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_UPDATE_CLEARED); - intentDeleted.putExtra(Downloader.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); + intentDeleted.putExtra(DownloaderService.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); intentDeleted.setClass(context, NotificationBroadcastReceiver.class); PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT); builder.setDeleteIntent(piDeleted); @@ -453,7 +453,7 @@ public class NotificationHelper { } Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_INSTALLED_CLEARED); - intentDeleted.putExtra(Downloader.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); + intentDeleted.putExtra(DownloaderService.EXTRA_CANONICAL_URL, entry.getCanonicalUrl()); intentDeleted.setClass(context, NotificationBroadcastReceiver.class); PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT); builder.setDeleteIntent(piDeleted); diff --git a/app/src/main/java/org/fdroid/fdroid/data/App.java b/app/src/main/java/org/fdroid/fdroid/data/App.java index 0697dd9ce..baf1f0465 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/App.java +++ b/app/src/main/java/org/fdroid/fdroid/data/App.java @@ -28,7 +28,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.io.filefilter.RegexFileFilter; import org.fdroid.download.DownloadRequest; -import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; diff --git a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java index ace7a8549..5081b587a 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java @@ -25,8 +25,8 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.net.DownloaderService; import androidx.annotation.NonNull; @@ -50,7 +50,7 @@ public class DefaultInstaller extends Installer { Intent installIntent = new Intent(context, DefaultInstallerActivity.class); installIntent.setAction(DefaultInstallerActivity.ACTION_INSTALL_PACKAGE); - installIntent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUri.toString()); + installIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); installIntent.putExtra(Installer.EXTRA_APK, apk); installIntent.setData(localApkUri); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java index 4e7541140..e41df2a3c 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java @@ -30,9 +30,9 @@ import android.os.Build; import android.os.Bundle; import android.util.Log; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.R; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.net.DownloaderService; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentActivity; @@ -69,7 +69,7 @@ public class DefaultInstallerActivity extends FragmentActivity { installer = new DefaultInstaller(this, apk); if (ACTION_INSTALL_PACKAGE.equals(action)) { Uri localApkUri = intent.getData(); - canonicalUri = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); installPackage(localApkUri); } else if (ACTION_UNINSTALL_PACKAGE.equals(action)) { uninstallPackage(apk.packageName); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java index 93341df66..1509bf2da 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java @@ -24,8 +24,8 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.net.DownloaderService; import androidx.annotation.NonNull; @@ -54,7 +54,7 @@ public class FileInstaller extends Installer { protected void installPackageInternal(Uri localApkUri, Uri canonicalUri) { Intent installIntent = new Intent(context, FileInstallerActivity.class); installIntent.setAction(FileInstallerActivity.ACTION_INSTALL_FILE); - installIntent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUri.toString()); + installIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); installIntent.putExtra(Installer.EXTRA_APK, apk); installIntent.setData(localApkUri); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java index c769fd204..ec3f50ee6 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java @@ -10,11 +10,11 @@ import android.view.ContextThemeWrapper; import android.widget.Toast; import org.apache.commons.io.FileUtils; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.net.DownloaderService; import java.io.File; import java.io.IOException; @@ -59,7 +59,7 @@ public class FileInstallerActivity extends FragmentActivity { apk = intent.getParcelableExtra(Installer.EXTRA_APK); installer = new FileInstaller(this, apk); if (ACTION_INSTALL_FILE.equals(action)) { - canonicalUri = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); if (hasStoragePermission()) { installPackage(localApkUri, canonicalUri, apk); } else { diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 56bb569af..d46437951 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -217,8 +217,8 @@ public class InstallManagerService extends Service { DownloaderService.queue(this, apk.repoId, canonicalUrl); } else if (ApkCache.apkIsCached(apkFilePath, apk)) { Utils.debugLog(TAG, "skip download, we have it, straight to install " + canonicalUrl + " " + apkFilePath); - sendBroadcast(intent.getData(), Downloader.ACTION_STARTED, apkFilePath); - sendBroadcast(intent.getData(), Downloader.ACTION_COMPLETE, apkFilePath); + sendBroadcast(intent.getData(), DownloaderService.ACTION_STARTED, apkFilePath); + sendBroadcast(intent.getData(), DownloaderService.ACTION_COMPLETE, apkFilePath); } else { Utils.debugLog(TAG, "delete and download again " + canonicalUrl + " " + apkFilePath); apkFilePath.delete(); @@ -231,7 +231,7 @@ public class InstallManagerService extends Service { private void sendBroadcast(Uri uri, String action, File file) { Intent intent = new Intent(action); intent.setData(uri); - intent.putExtra(Downloader.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath()); + intent.putExtra(DownloaderService.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath()); localBroadcastManager.sendBroadcast(intent); } @@ -263,16 +263,16 @@ public class InstallManagerService extends Service { return; } String action = intent.getAction(); - if (Downloader.ACTION_STARTED.equals(action)) { + if (DownloaderService.ACTION_STARTED.equals(action)) { Utils.debugLog(TAG, action + " " + intent); - } else if (Downloader.ACTION_PROGRESS.equals(action)) { + } else if (DownloaderService.ACTION_PROGRESS.equals(action)) { - long bytesRead = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); - long totalBytes = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + long bytesRead = intent.getLongExtra(DownloaderService.EXTRA_BYTES_READ, 0); + long totalBytes = intent.getLongExtra(DownloaderService.EXTRA_TOTAL_BYTES, 0); appUpdateStatusManager.updateApkProgress(canonicalUrl, totalBytes, bytesRead); - } else if (Downloader.ACTION_COMPLETE.equals(action)) { + } else if (DownloaderService.ACTION_COMPLETE.equals(action)) { localBroadcastManager.unregisterReceiver(this); - File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH)); + File localFile = new File(intent.getStringExtra(DownloaderService.EXTRA_DOWNLOAD_PATH)); Uri localApkUri = Uri.fromFile(localFile); Utils.debugLog(TAG, "OBB download completed " + intent.getDataString() + " to " + localApkUri); @@ -298,9 +298,9 @@ public class InstallManagerService extends Service { } finally { FileUtils.deleteQuietly(localFile); } - } else if (Downloader.ACTION_INTERRUPTED.equals(action)) { + } else if (DownloaderService.ACTION_INTERRUPTED.equals(action)) { localBroadcastManager.unregisterReceiver(this); - } else if (Downloader.ACTION_CONNECTION_FAILED.equals(action)) { + } else if (DownloaderService.ACTION_CONNECTION_FAILED.equals(action)) { localBroadcastManager.unregisterReceiver(this); } else { throw new RuntimeException("intent action not handled!"); @@ -329,7 +329,7 @@ public class InstallManagerService extends Service { String canonicalUrl = intent.getDataString(); switch (intent.getAction()) { - case Downloader.ACTION_STARTED: + case DownloaderService.ACTION_STARTED: // App should currently be in the "PendingDownload" state, so this changes it to "Downloading". Intent intentObject = new Intent(context, InstallManagerService.class); intentObject.setAction(ACTION_CANCEL); @@ -338,17 +338,17 @@ public class InstallManagerService extends Service { appUpdateStatusManager.updateApk(canonicalUrl, AppUpdateStatusManager.Status.Downloading, action); break; - case Downloader.ACTION_PROGRESS: - long bytesRead = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); - long totalBytes = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + case DownloaderService.ACTION_PROGRESS: + long bytesRead = intent.getLongExtra(DownloaderService.EXTRA_BYTES_READ, 0); + long totalBytes = intent.getLongExtra(DownloaderService.EXTRA_TOTAL_BYTES, 0); appUpdateStatusManager.updateApkProgress(canonicalUrl, totalBytes, bytesRead); break; - case Downloader.ACTION_COMPLETE: - File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH)); + case DownloaderService.ACTION_COMPLETE: + File localFile = new File(intent.getStringExtra(DownloaderService.EXTRA_DOWNLOAD_PATH)); Uri localApkUri = Uri.fromFile(localFile); Utils.debugLog(TAG, "download completed of " - + intent.getStringExtra(Downloader.EXTRA_MIRROR_URL) + " to " + localApkUri); + + intent.getStringExtra(DownloaderService.EXTRA_MIRROR_URL) + " to " + localApkUri); appUpdateStatusManager.updateApk(canonicalUrl, AppUpdateStatusManager.Status.ReadyToInstall, null); @@ -360,10 +360,10 @@ public class InstallManagerService extends Service { InstallerService.install(context, localApkUri, canonicalUri, apk); } break; - case Downloader.ACTION_INTERRUPTED: - case Downloader.ACTION_CONNECTION_FAILED: + case DownloaderService.ACTION_INTERRUPTED: + case DownloaderService.ACTION_CONNECTION_FAILED: appUpdateStatusManager.setDownloadError(canonicalUrl, - intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE)); + intent.getStringExtra(DownloaderService.EXTRA_ERROR_MESSAGE)); localBroadcastManager.unregisterReceiver(this); break; default: diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java index 6a7052348..ea0ef4c55 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java @@ -27,10 +27,10 @@ import android.os.Build; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.App; +import org.fdroid.fdroid.net.DownloaderService; import org.fdroid.fdroid.views.AppDetailsActivity; import java.io.File; @@ -77,7 +77,7 @@ public class InstallerService extends JobIntentService { if (ACTION_INSTALL.equals(intent.getAction())) { Uri uri = intent.getData(); - Uri canonicalUri = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + Uri canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); installer.installPackage(uri, canonicalUri); } else if (ACTION_UNINSTALL.equals(intent.getAction())) { installer.uninstallPackage(); @@ -127,7 +127,7 @@ public class InstallerService extends JobIntentService { Intent intent = new Intent(context, InstallerService.class); intent.setAction(ACTION_INSTALL); intent.setData(localApkUri); - intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUri.toString()); + intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); intent.putExtra(Installer.EXTRA_APK, apk); enqueueWork(context, intent); } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java b/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java index 1109ee03e..edc1f800b 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java @@ -12,8 +12,8 @@ import android.util.Log; import android.webkit.MimeTypeMap; import org.apache.commons.io.FileUtils; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.net.DownloaderService; import java.io.File; import java.io.IOException; @@ -41,7 +41,7 @@ public class ObfInstallerService extends IntentService { public static void install(Context context, Uri canonicalUri, Apk apk, File path) { Intent intent = new Intent(context, ObfInstallerService.class); intent.setAction(ACTION_INSTALL_OBF); - intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUri.toString()); + intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); intent.putExtra(Installer.EXTRA_APK, apk); intent.putExtra(EXTRA_OBF_PATH, path.getAbsolutePath()); context.startService(intent); @@ -53,7 +53,7 @@ public class ObfInstallerService extends IntentService { Log.e(TAG, "received invalid intent: " + intent); return; } - Uri canonicalUri = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + Uri canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); final Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); final String path = intent.getStringExtra(EXTRA_OBF_PATH); final String extension = MimeTypeMap.getFileExtensionFromUrl(path); diff --git a/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java b/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java index 345011d77..5eb2bdf0b 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java @@ -99,6 +99,29 @@ public class DownloaderService extends Service { private static final String ACTION_QUEUE = "org.fdroid.fdroid.net.DownloaderService.action.QUEUE"; private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL"; + public static final String ACTION_STARTED = "org.fdroid.fdroid.net.Downloader.action.STARTED"; + public static final String ACTION_PROGRESS = "org.fdroid.fdroid.net.Downloader.action.PROGRESS"; + public static final String ACTION_INTERRUPTED = "org.fdroid.fdroid.net.Downloader.action.INTERRUPTED"; + public static final String ACTION_CONNECTION_FAILED = "org.fdroid.fdroid.net.Downloader.action.CONNECTION_FAILED"; + public static final String ACTION_COMPLETE = "org.fdroid.fdroid.net.Downloader.action.COMPLETE"; + + public static final String EXTRA_DOWNLOAD_PATH = "org.fdroid.fdroid.net.Downloader.extra.DOWNLOAD_PATH"; + public static final String EXTRA_BYTES_READ = "org.fdroid.fdroid.net.Downloader.extra.BYTES_READ"; + public static final String EXTRA_TOTAL_BYTES = "org.fdroid.fdroid.net.Downloader.extra.TOTAL_BYTES"; + public static final String EXTRA_ERROR_MESSAGE = "org.fdroid.fdroid.net.Downloader.extra.ERROR_MESSAGE"; + public static final String EXTRA_REPO_ID = "org.fdroid.fdroid.net.Downloader.extra.REPO_ID"; + public static final String EXTRA_MIRROR_URL = "org.fdroid.fdroid.net.Downloader.extra.MIRROR_URL"; + /** + * Unique ID used to represent this specific package's install process, + * including {@link android.app.Notification}s, also known as {@code canonicalUrl}. + * Careful about types, this should always be a {@link String}, so it can + * be handled on the receiving side by {@link android.content.Intent#getStringArrayExtra(String)}. + * + * @see org.fdroid.fdroid.installer.InstallManagerService + * @see android.content.Intent#EXTRA_ORIGINATING_URI + */ + public static final String EXTRA_CANONICAL_URL = "org.fdroid.fdroid.net.Downloader.extra.CANONICAL_URL"; + private volatile Looper serviceLooper; private static volatile ServiceHandler serviceHandler; private static volatile Downloader downloader; @@ -149,7 +172,7 @@ public class DownloaderService extends Service { Utils.debugLog(TAG, "Received Intent with no URI: " + intent); return START_NOT_STICKY; } - String canonicalUrl = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL); + String canonicalUrl = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL); if (canonicalUrl == null) { Utils.debugLog(TAG, "Received Intent with no EXTRA_CANONICAL_URL: " + intent); return START_NOT_STICKY; @@ -218,10 +241,10 @@ public class DownloaderService extends Service { */ private void handleIntent(Intent intent) { final Uri uri = intent.getData(); - final long repoId = intent.getLongExtra(Downloader.EXTRA_REPO_ID, 0); - final Uri canonicalUrl = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + final long repoId = intent.getLongExtra(DownloaderService.EXTRA_REPO_ID, 0); + final Uri canonicalUrl = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); final SanitizedFile localFile = ApkCache.getApkDownloadPath(this, canonicalUrl); - sendBroadcast(uri, Downloader.ACTION_STARTED, localFile, repoId, canonicalUrl); + sendBroadcast(uri, DownloaderService.ACTION_STARTED, localFile, repoId, canonicalUrl); try { activeCanonicalUrl = canonicalUrl.toString(); @@ -230,26 +253,26 @@ public class DownloaderService extends Service { downloader.setListener(new ProgressListener() { @Override public void onProgress(long bytesRead, long totalBytes) { - Intent intent = new Intent(Downloader.ACTION_PROGRESS); + Intent intent = new Intent(DownloaderService.ACTION_PROGRESS); intent.setData(canonicalUrl); - intent.putExtra(Downloader.EXTRA_BYTES_READ, bytesRead); - intent.putExtra(Downloader.EXTRA_TOTAL_BYTES, totalBytes); + intent.putExtra(DownloaderService.EXTRA_BYTES_READ, bytesRead); + intent.putExtra(DownloaderService.EXTRA_TOTAL_BYTES, totalBytes); localBroadcastManager.sendBroadcast(intent); } }); downloader.download(); - sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile, repoId, canonicalUrl); + sendBroadcast(uri, DownloaderService.ACTION_COMPLETE, localFile, repoId, canonicalUrl); } catch (InterruptedException e) { - sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, canonicalUrl); + sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, localFile, repoId, canonicalUrl); } catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException | SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException | ProtocolException | UnknownHostException e) { // if the above list of exceptions changes, also change it in IndexV1Updater.update() Log.e(TAG, "CONNECTION_FAILED: " + e.getLocalizedMessage()); - sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, canonicalUrl); + sendBroadcast(uri, DownloaderService.ACTION_CONNECTION_FAILED, localFile, repoId, canonicalUrl); } catch (IOException e) { e.printStackTrace(); - sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, + sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, localFile, e.getLocalizedMessage(), repoId, canonicalUrl); } finally { if (downloader != null) { @@ -261,7 +284,7 @@ public class DownloaderService extends Service { } private void sendCancelledBroadcast(Uri uri, String canonicalUrl) { - sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, null, 0, Uri.parse(canonicalUrl)); + sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, null, 0, Uri.parse(canonicalUrl)); } private void sendBroadcast(Uri uri, String action, File file, long repoId, Uri canonicalUrl) { @@ -275,13 +298,13 @@ public class DownloaderService extends Service { intent.setData(canonicalUrl); } if (file != null) { - intent.putExtra(Downloader.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath()); + intent.putExtra(DownloaderService.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath()); } if (!TextUtils.isEmpty(errorMessage)) { - intent.putExtra(Downloader.EXTRA_ERROR_MESSAGE, errorMessage); + intent.putExtra(DownloaderService.EXTRA_ERROR_MESSAGE, errorMessage); } - intent.putExtra(Downloader.EXTRA_REPO_ID, repoId); - intent.putExtra(Downloader.EXTRA_MIRROR_URL, uri.toString()); + intent.putExtra(DownloaderService.EXTRA_REPO_ID, repoId); + intent.putExtra(DownloaderService.EXTRA_MIRROR_URL, uri.toString()); localBroadcastManager.sendBroadcast(intent); } @@ -303,8 +326,8 @@ public class DownloaderService extends Service { Intent intent = new Intent(context, DownloaderService.class); intent.setAction(ACTION_QUEUE); intent.setData(Uri.parse(canonicalUrl)); - intent.putExtra(Downloader.EXTRA_REPO_ID, repoId); - intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUrl); + intent.putExtra(DownloaderService.EXTRA_REPO_ID, repoId); + intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUrl); context.startService(intent); } @@ -325,7 +348,7 @@ public class DownloaderService extends Service { Intent intent = new Intent(context, DownloaderService.class); intent.setAction(ACTION_CANCEL); intent.setData(Uri.parse(canonicalUrl)); - intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUrl); + intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUrl); context.startService(intent); } @@ -359,11 +382,11 @@ public class DownloaderService extends Service { public static IntentFilter getIntentFilter(String canonicalUrl) { Uri uri = Uri.parse(canonicalUrl); IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Downloader.ACTION_STARTED); - intentFilter.addAction(Downloader.ACTION_PROGRESS); - intentFilter.addAction(Downloader.ACTION_COMPLETE); - intentFilter.addAction(Downloader.ACTION_INTERRUPTED); - intentFilter.addAction(Downloader.ACTION_CONNECTION_FAILED); + intentFilter.addAction(DownloaderService.ACTION_STARTED); + intentFilter.addAction(DownloaderService.ACTION_PROGRESS); + intentFilter.addAction(DownloaderService.ACTION_COMPLETE); + intentFilter.addAction(DownloaderService.ACTION_INTERRUPTED); + intentFilter.addAction(DownloaderService.ACTION_CONNECTION_FAILED); intentFilter.addDataScheme(uri.getScheme()); intentFilter.addDataAuthority(uri.getHost(), String.valueOf(uri.getPort())); intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL); diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java index 484be52bc..939ceb878 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java @@ -45,7 +45,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.badge.BadgeDrawable; import com.google.android.material.bottomnavigation.BottomNavigationView; -import org.fdroid.download.Downloader; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus; import org.fdroid.fdroid.FDroidApp; @@ -60,6 +59,7 @@ import org.fdroid.fdroid.nearby.SwapService; import org.fdroid.fdroid.nearby.SwapWorkflowActivity; import org.fdroid.fdroid.nearby.TreeUriScannerIntentService; import org.fdroid.fdroid.nearby.WifiStateChangeService; +import org.fdroid.fdroid.net.DownloaderService; import org.fdroid.fdroid.views.AppDetailsActivity; import org.fdroid.fdroid.views.ManageReposActivity; import org.fdroid.fdroid.views.apps.AppListActivity; @@ -431,7 +431,7 @@ public class MainActivity extends AppCompatActivity { // Check if we have moved into the ReadyToInstall or Installed state. AppUpdateStatus status = manager.get( - intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL)); + intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); boolean isStatusChange = intent.getBooleanExtra(AppUpdateStatusManager.EXTRA_IS_STATUS_UPDATE, false); if (isStatusChange && status != null diff --git a/build.gradle b/build.gradle index b4f3ab20e..6bacf66a4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,11 @@ buildscript { - ext { - kotlin_version = "1.6.10" - glide_version = "4.12.0" - } repositories { mavenCentral() maven { url 'https://maven.google.com/' } } dependencies { classpath 'com.android.tools.build:gradle:3.6.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" } } allprojects { diff --git a/download/build.gradle b/download/build.gradle index 76340f562..432296b9d 100644 --- a/download/build.gradle +++ b/download/build.gradle @@ -1,6 +1,7 @@ plugins { id 'org.jetbrains.kotlin.multiplatform' id 'com.android.library' + id "org.jlleitschuh.gradle.ktlint" version "10.1.0" } group = 'org.fdroid' @@ -28,8 +29,7 @@ kotlin { all { languageSettings { optIn('kotlin.RequiresOptIn') - explicitApi() - explicitApi = 'strict' + explicitApi('strict') } } commonMain { @@ -58,10 +58,10 @@ kotlin { androidMain { dependencies { implementation "io.ktor:ktor-client-okhttp:$ktor_version" - implementation("com.github.bumptech.glide:glide:$glide_version") { + implementation("com.github.bumptech.glide:glide:4.12.0") { transitive = false // we don't need all that it pulls in, just the basics } - implementation "com.github.bumptech.glide:annotations:$glide_version" + implementation "com.github.bumptech.glide:annotations:4.12.0" implementation 'ch.qos.logback:logback-classic:1.2.5' } } @@ -96,3 +96,5 @@ android { disable "InvalidPackage" // FIXME remove when Ktor 2.0 has been released } } + +apply from: "${rootProject.rootDir}/gradle/ktlint.gradle" diff --git a/download/src/androidMain/kotlin/org/fdroid/download/Downloader.kt b/download/src/androidMain/kotlin/org/fdroid/download/Downloader.kt index 67ddb24c7..7b6f5ece0 100644 --- a/download/src/androidMain/kotlin/org/fdroid/download/Downloader.kt +++ b/download/src/androidMain/kotlin/org/fdroid/download/Downloader.kt @@ -15,29 +15,6 @@ public abstract class Downloader constructor( public companion object { private val log = KotlinLogging.logger {} - - public const val ACTION_STARTED: String = "org.fdroid.fdroid.net.Downloader.action.STARTED" - public const val ACTION_PROGRESS: String = "org.fdroid.fdroid.net.Downloader.action.PROGRESS" - public const val ACTION_INTERRUPTED: String = "org.fdroid.fdroid.net.Downloader.action.INTERRUPTED" - public const val ACTION_CONNECTION_FAILED: String = - "org.fdroid.fdroid.net.Downloader.action.CONNECTION_FAILED" - public const val ACTION_COMPLETE: String = "org.fdroid.fdroid.net.Downloader.action.COMPLETE" - public const val EXTRA_DOWNLOAD_PATH: String = "org.fdroid.fdroid.net.Downloader.extra.DOWNLOAD_PATH" - public const val EXTRA_BYTES_READ: String = "org.fdroid.fdroid.net.Downloader.extra.BYTES_READ" - public const val EXTRA_TOTAL_BYTES: String = "org.fdroid.fdroid.net.Downloader.extra.TOTAL_BYTES" - public const val EXTRA_ERROR_MESSAGE: String = "org.fdroid.fdroid.net.Downloader.extra.ERROR_MESSAGE" - public const val EXTRA_REPO_ID: String = "org.fdroid.fdroid.net.Downloader.extra.REPO_ID" - public const val EXTRA_MIRROR_URL: String = "org.fdroid.fdroid.net.Downloader.extra.MIRROR_URL" - - /** - * Unique ID used to represent this specific package's install process, - * including [android.app.Notification]s, also known as `canonicalUrl`. - * Careful about types, this should always be a [String], so it can - * be handled on the receiving side by [android.content.Intent.getStringArrayExtra]. - * - * @see android.content.Intent.EXTRA_ORIGINATING_URI - */ - public const val EXTRA_CANONICAL_URL: String = "org.fdroid.fdroid.net.Downloader.extra.CANONICAL_URL" } /** diff --git a/download/src/androidMain/kotlin/org/fdroid/download/HttpDownloader.kt b/download/src/androidMain/kotlin/org/fdroid/download/HttpDownloader.kt index 03891edb8..ad63e8d03 100644 --- a/download/src/androidMain/kotlin/org/fdroid/download/HttpDownloader.kt +++ b/download/src/androidMain/kotlin/org/fdroid/download/HttpDownloader.kt @@ -140,10 +140,12 @@ public class HttpDownloader constructor( var resumable = false val fileLength = outputFile.length() if (fileLength > fileSize) { - if (!outputFile.delete()) log.warn { "Warning: " + outputFile.absolutePath + " not deleted" } + if (!outputFile.delete()) log.warn { + "Warning: " + outputFile.absolutePath + " not deleted" + } } else if (fileLength == fileSize && outputFile.isFile) { log.debug { "Already have outputFile, not download. ${outputFile.absolutePath}" } - return // already have it! + return // already have it! } else if (fileLength > 0) { resumable = true } @@ -153,7 +155,9 @@ public class HttpDownloader constructor( downloadFromBytesReceiver(resumable) } catch (e: NoResumeException) { require(resumable) { "Got $e even though download was not resumable" } - if (!outputFile.delete()) log.warn { "Warning: " + outputFile.absolutePath + " not deleted" } + if (!outputFile.delete()) log.warn { + "Warning: " + outputFile.absolutePath + " not deleted" + } downloadFromBytesReceiver(false) } } diff --git a/download/src/androidMain/kotlin/org/fdroid/download/glide/DownloadRequestLoader.kt b/download/src/androidMain/kotlin/org/fdroid/download/glide/DownloadRequestLoader.kt index fc8e3b06f..85cd78a61 100644 --- a/download/src/androidMain/kotlin/org/fdroid/download/glide/DownloadRequestLoader.kt +++ b/download/src/androidMain/kotlin/org/fdroid/download/glide/DownloadRequestLoader.kt @@ -30,7 +30,9 @@ public class DownloadRequestLoader( public class Factory( private val httpManager: HttpManager, ) : ModelLoaderFactory { - override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { + override fun build( + multiFactory: MultiModelLoaderFactory, + ): ModelLoader { return DownloadRequestLoader(httpManager) } diff --git a/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpFetcher.kt b/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpFetcher.kt index cb1c3f9a6..c5af5fc64 100644 --- a/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpFetcher.kt +++ b/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpFetcher.kt @@ -25,7 +25,8 @@ internal class HttpFetcher( @Deprecated("Use DownloadRequests with other constructor instead") constructor( httpManager: HttpManager, - glideUrl: GlideUrl, proxy: ProxyConfig?, + glideUrl: GlideUrl, + proxy: ProxyConfig?, ) : this(httpManager, getDownloadRequest(glideUrl, proxy)) companion object { diff --git a/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpGlideUrlLoader.kt b/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpGlideUrlLoader.kt index ff456e0db..5eef32f50 100644 --- a/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpGlideUrlLoader.kt +++ b/download/src/androidMain/kotlin/org/fdroid/download/glide/HttpGlideUrlLoader.kt @@ -25,7 +25,12 @@ public class HttpGlideUrlLoader( return true } - override fun buildLoadData(glideUrl: GlideUrl, width: Int, height: Int, options: Options): LoadData { + override fun buildLoadData( + glideUrl: GlideUrl, + width: Int, + height: Int, + options: Options, + ): LoadData { log.warn { "Not using mirrors when loading $glideUrl" } return LoadData(glideUrl, HttpFetcher(httpManager, glideUrl, proxyGetter())) } @@ -34,7 +39,9 @@ public class HttpGlideUrlLoader( private val httpManager: HttpManager, private val proxyGetter: () -> ProxyConfig?, ) : ModelLoaderFactory { - override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { + override fun build( + multiFactory: MultiModelLoaderFactory, + ): ModelLoader { return HttpGlideUrlLoader(httpManager, proxyGetter) } diff --git a/download/src/androidTest/kotlin/org/fdroid/download/HttpDownloaderTest.kt b/download/src/androidTest/kotlin/org/fdroid/download/HttpDownloaderTest.kt index 79f2401bb..67732da76 100644 --- a/download/src/androidTest/kotlin/org/fdroid/download/HttpDownloaderTest.kt +++ b/download/src/androidTest/kotlin/org/fdroid/download/HttpDownloaderTest.kt @@ -159,7 +159,8 @@ class HttpDownloaderTest { val file = folder.newFile() val httpManager = HttpManager(userAgent, null) - val torHost = "http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion" // tor-project.org + // tor-project.org + val torHost = "http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion" val proxy = ProxyBuilder.socks("localhost", TOR_SOCKS_PORT) val downloadRequest = DownloadRequest("index.html", listOf(Mirror(torHost)), proxy) val httpDownloader = HttpDownloader(httpManager, downloadRequest, file) diff --git a/download/src/commonMain/kotlin/org/fdroid/download/HttpManager.kt b/download/src/commonMain/kotlin/org/fdroid/download/HttpManager.kt index e0a9de068..06944832d 100644 --- a/download/src/commonMain/kotlin/org/fdroid/download/HttpManager.kt +++ b/download/src/commonMain/kotlin/org/fdroid/download/HttpManager.kt @@ -157,7 +157,7 @@ public open class HttpManager @JvmOverloads constructor( // increase connect timeout if using Tor mirror if (mirror.isOnion()) timeout { connectTimeoutMillis = 20_000 } // add range header if set - if (skipFirstBytes != null) header(Range, "bytes=${skipFirstBytes}-") + if (skipFirstBytes != null) header(Range, "bytes=$skipFirstBytes-") } } } @@ -178,7 +178,10 @@ public open class HttpManager @JvmOverloads constructor( * Thus, this is intentionally visible internally only. * Does not use [getChannel] so, it gets the [NoResumeException] as in the public API. */ - internal suspend fun getBytes(request: DownloadRequest, skipFirstBytes: Long? = null): ByteArray { + internal suspend fun getBytes( + request: DownloadRequest, + skipFirstBytes: Long? = null, + ): ByteArray { val channel = ByteChannel() get(request, skipFirstBytes) { bytes -> channel.writeFully(bytes) @@ -198,7 +201,9 @@ public open class HttpManager @JvmOverloads constructor( private fun resetProxyIfNeeded(proxyConfig: ProxyConfig?, mirror: Mirror? = null) { // force no-proxy when trying to hit a local mirror val newProxy = if (mirror.isLocal() && proxyConfig != null) { - if (currentProxy != null) log.info { "Forcing mirror to null, because mirror is local: $mirror" } + if (currentProxy != null) log.info { + "Forcing mirror to null, because mirror is local: $mirror" + } null } else proxyConfig if (currentProxy != newProxy) { diff --git a/download/src/commonMain/kotlin/org/fdroid/download/Mirror.kt b/download/src/commonMain/kotlin/org/fdroid/download/Mirror.kt index 7ee34d047..cbf885c10 100644 --- a/download/src/commonMain/kotlin/org/fdroid/download/Mirror.kt +++ b/download/src/commonMain/kotlin/org/fdroid/download/Mirror.kt @@ -58,7 +58,7 @@ internal fun Url.isLocal(): Boolean { return num in 16..31 } return host.startsWith("169.254.") || - host.startsWith("10.") || - host.startsWith("192.168.") || - host == "127.0.0.1" + host.startsWith("10.") || + host.startsWith("192.168.") || + host == "127.0.0.1" } diff --git a/download/src/commonMain/kotlin/org/fdroid/download/MirrorChooser.kt b/download/src/commonMain/kotlin/org/fdroid/download/MirrorChooser.kt index bea654056..568224dfc 100644 --- a/download/src/commonMain/kotlin/org/fdroid/download/MirrorChooser.kt +++ b/download/src/commonMain/kotlin/org/fdroid/download/MirrorChooser.kt @@ -27,9 +27,10 @@ internal abstract class MirrorChooserImpl : MirrorChooser { ): T { val mirrors = if (downloadRequest.proxy == null) { // if we don't use a proxy, filter out onion mirrors (won't work without Orbot) - val orderedMirrors = orderMirrors(downloadRequest).filter { mirror -> !mirror.isOnion() } + val orderedMirrors = + orderMirrors(downloadRequest).filter { mirror -> !mirror.isOnion() } // if we only have onion mirrors, take what we have and expect errors - if (orderedMirrors.isEmpty()) downloadRequest.mirrors else orderedMirrors + orderedMirrors.ifEmpty { downloadRequest.mirrors } } else { orderMirrors(downloadRequest) } @@ -39,7 +40,10 @@ internal abstract class MirrorChooserImpl : MirrorChooser { return request(mirror, url) } catch (e: ResponseException) { val wasLastMirror = index == downloadRequest.mirrors.size - 1 - log.warn(e) { if (wasLastMirror) "Last mirror, rethrowing..." else "Trying other mirror now..." } + log.warn(e) { + if (wasLastMirror) "Last mirror, rethrowing..." + else "Trying other mirror now..." + } if (wasLastMirror) throw e } } diff --git a/download/src/commonMain/kotlin/org/fdroid/download/Proxy.kt b/download/src/commonMain/kotlin/org/fdroid/download/Proxy.kt index ae34e1581..aefeb7e04 100644 --- a/download/src/commonMain/kotlin/org/fdroid/download/Proxy.kt +++ b/download/src/commonMain/kotlin/org/fdroid/download/Proxy.kt @@ -16,5 +16,5 @@ internal fun ProxyConfig?.isTor(): Boolean { if (this == null || !hostIsIp(DEFAULT_PROXY_HOST)) return false val address = resolveAddress() return (type == HTTP && address.port == DEFAULT_PROXY_HTTP_PORT) || - (type == SOCKS && address.port == DEFAULT_PROXY_SOCKS_PORT) + (type == SOCKS && address.port == DEFAULT_PROXY_SOCKS_PORT) } diff --git a/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerIntegrationTest.kt b/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerIntegrationTest.kt index a19fb439a..2b3903fac 100644 --- a/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerIntegrationTest.kt +++ b/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerIntegrationTest.kt @@ -2,9 +2,9 @@ package org.fdroid.download import io.ktor.client.engine.ProxyBuilder import io.ktor.http.Url +import io.ktor.utils.io.errors.IOException import org.fdroid.getRandomString import org.fdroid.runSuspend -import java.net.ConnectException import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -28,7 +28,7 @@ class HttpManagerIntegrationTest { val proxyRequest = downloadRequest.copy(proxy = ProxyBuilder.http(Url("http://127.0.0.1"))) val httpManager = HttpManager(userAgent, null) - val e = assertFailsWith { + val e = assertFailsWith { httpManager.getBytes(proxyRequest) } assertEquals("Failed to connect to /127.0.0.1:80", e.message) diff --git a/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerTest.kt b/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerTest.kt index 83a243565..0149349f7 100644 --- a/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerTest.kt +++ b/download/src/commonTest/kotlin/org/fdroid/download/HttpManagerTest.kt @@ -60,7 +60,8 @@ class HttpManagerTest { val version = getRandomString() val queryString = "id=$id&client_version=$version" val mockEngine = MockEngine { respondOk() } - val httpManager = HttpManager(userAgent, queryString, httpClientEngineFactory = get(mockEngine)) + val httpManager = + HttpManager(userAgent, queryString, httpClientEngineFactory = get(mockEngine)) httpManager.head(downloadRequest) httpManager.getBytes(downloadRequest) @@ -119,8 +120,11 @@ class HttpManagerTest { var requestNum = 1 val mockEngine = MockEngine { request -> assertNotNull(request.headers[Range]) - val (fromStr, endStr) = request.headers[Range]!!.replace("bytes=", "").split('-') - val from = fromStr.toIntOrNull() ?: fail("No valid content range ${request.headers[Range]}") + val (fromStr, endStr) = request.headers[Range]!! + .replace("bytes=", "") + .split('-') + val from = + fromStr.toIntOrNull() ?: fail("No valid content range ${request.headers[Range]}") assertEquals("", endStr) assertEquals(skipBytes, from) if (requestNum++ == 1) respond(content.copyOfRange(from, content.size), PartialContent) @@ -129,8 +133,10 @@ class HttpManagerTest { val httpManager = HttpManager(userAgent, null, httpClientEngineFactory = get(mockEngine)) // first request gets only the skipped bytes - assertContentEquals(content.copyOfRange(skipBytes, content.size), - httpManager.getBytes(downloadRequest, skipBytes.toLong())) + assertContentEquals( + content.copyOfRange(skipBytes, content.size), + httpManager.getBytes(downloadRequest, skipBytes.toLong()) + ) // second request fails, because it responds with OK and full content assertFailsWith { httpManager.getBytes(downloadRequest, skipBytes.toLong()) @@ -238,7 +244,8 @@ class HttpManagerTest { } } } - val httpManager = HttpManager(userAgent, null, proxyConfig, httpClientEngineFactory = factory) + val httpManager = + HttpManager(userAgent, null, proxyConfig, httpClientEngineFactory = factory) assertEquals(proxyConfig, httpManager.currentProxy) // does not need a new engine, because also does use a proxy (1) diff --git a/download/src/commonTest/kotlin/org/fdroid/download/MirrorTest.kt b/download/src/commonTest/kotlin/org/fdroid/download/MirrorTest.kt index 40c6c8d59..72dacead4 100644 --- a/download/src/commonTest/kotlin/org/fdroid/download/MirrorTest.kt +++ b/download/src/commonTest/kotlin/org/fdroid/download/MirrorTest.kt @@ -22,7 +22,11 @@ class MirrorTest { @Test fun testIsOnion() { - assertTrue(Mirror("http://ftpfaudev4triw2vxiwzf4334e3mynz7osqgtozhbc77fixncqzbyoyd.onion/fdroid/repo").isOnion()) + assertTrue( + Mirror( + "http://ftpfaudev4triw2vxiwzf4334e3mynz7osqgtozhbc77fixncqzbyoyd.onion/fdroid/repo" + ).isOnion() + ) assertFalse(Mirror("https://www.f-droid.org/fdroid/repo").isOnion()) assertFalse(Mirror("http://192.168.0.1/fdroid/repo").isOnion()) } diff --git a/gradle/ktlint.gradle b/gradle/ktlint.gradle new file mode 100644 index 000000000..60fada8f6 --- /dev/null +++ b/gradle/ktlint.gradle @@ -0,0 +1,10 @@ +ktlint { + version = "0.43.2" + android = true + enableExperimentalRules = false + verbose = true + disabledRules = [ + "import-ordering", + "no-blank-line-before-rbrace", + ] +} diff --git a/gradle/verification-keyring.gpg b/gradle/verification-keyring.gpg index 9d19b2644..07af56b4a 100644 Binary files a/gradle/verification-keyring.gpg and b/gradle/verification-keyring.gpg differ diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 80c17597a..83d0559ec 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -7,6 +7,10 @@ + + + + @@ -99,11 +103,16 @@ + + + + + @@ -861,6 +870,16 @@ + + + + + + + + + + @@ -1477,6 +1496,12 @@ + + + + + + @@ -1671,14 +1696,10 @@ - - - - - + @@ -1942,6 +1963,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1978,6 +2054,11 @@ + + + + + @@ -1988,6 +2069,11 @@ + + + + + @@ -2148,11 +2234,30 @@ + + + + + + + + + + + + + + + + + + + @@ -2199,6 +2304,9 @@ + + + @@ -2307,6 +2415,9 @@ + + + @@ -2320,6 +2431,9 @@ + + + @@ -2370,6 +2484,9 @@ + + + @@ -2467,6 +2584,9 @@ + + + @@ -2648,6 +2768,7 @@ + @@ -3300,6 +3421,12 @@ + + + + + + @@ -3399,6 +3526,11 @@ + + + + + @@ -3414,6 +3546,11 @@ + + + + + @@ -3439,6 +3576,11 @@ + + + + + @@ -3462,6 +3604,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -3490,6 +3652,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -3498,6 +3680,21 @@ + + + + + + + + + + + + + + + @@ -3506,6 +3703,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -3514,6 +3731,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3566,16 +3828,29 @@ + + + + + + + + + + + + + @@ -3589,11 +3864,21 @@ + + + + + + + + + + @@ -3607,6 +3892,11 @@ + + + + + @@ -3849,6 +4139,7 @@ + diff --git a/tools/update-verification-metadata.sh b/tools/update-verification-metadata.sh index 9a8482868..db72f70e9 100755 --- a/tools/update-verification-metadata.sh +++ b/tools/update-verification-metadata.sh @@ -3,8 +3,15 @@ TOOLS_DIR=$(cd "$(dirname "$0")"; pwd) cd "$TOOLS_DIR"/.. -./gradlew --write-verification-metadata pgp,sha256 build connectedCheck assembleFullDebug +./gradlew --write-verification-metadata pgp,sha256 \ + build \ + assembleFullDebug \ + loadKtlintReporters \ + -x :app:test \ + -x :app:lint \ + -x :download:nativeTest +printf "\nIf you changed dependencies related to tests, also add 'test' or 'connectedCheck'.\n\n" printf "\nPlease review the following diff:\n\n" git diff gradle/verification-metadata.xml