diff --git a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt index 9c12ab067..2276d585b 100644 --- a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt +++ b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt @@ -22,7 +22,7 @@ import org.schabi.newpipe.extractor.downloader.Response import org.schabi.newpipe.extractor.exceptions.ReCaptchaException import org.schabi.newpipe.util.ReleaseVersionUtil.coerceUpdateCheckExpiry import org.schabi.newpipe.util.ReleaseVersionUtil.isLastUpdateCheckExpired -import org.schabi.newpipe.util.ReleaseVersionUtil.isReleaseApk +import org.schabi.newpipe.util.Version import java.io.IOException class NewVersionWorker( @@ -30,20 +30,15 @@ class NewVersionWorker( workerParams: WorkerParameters ) : Worker(context, workerParams) { - /** - * Method to compare the current and latest available app version. - * If a newer version is available, we show the update notification. - * - * @param versionName Name of new version - * @param apkLocationUrl Url with the new apk - * @param versionCode Code of new version - */ private fun compareAppVersionAndShowNotification( versionName: String, - apkLocationUrl: String?, - versionCode: Int + apkLocationUrl: String? ) { - if (BuildConfig.VERSION_CODE >= versionCode) { + val ourVersion = Version.fromString(BuildConfig.VERSION_NAME) + val theirVersion = Version.fromString(versionName) + + // abort if source version is the same or newer than target version + if (ourVersion >= theirVersion) { if (inputData.getBoolean(IS_MANUAL, false)) { // Show toast stating that the app is up-to-date if the update check was manual. ContextCompat.getMainExecutor(applicationContext).execute { @@ -83,11 +78,6 @@ class NewVersionWorker( @Throws(IOException::class, ReCaptchaException::class) private fun checkNewVersion() { - // Check if the current apk is a github one or not. - if (!isReleaseApk()) { - return - } - if (!inputData.getBoolean(IS_MANUAL, false)) { val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext) // Check if the last request has happened a certain time ago @@ -120,19 +110,16 @@ class NewVersionWorker( // Parse the json from the response. try { - val newpipeVersionInfo = JsonParser.`object`() - .from(response.responseBody()).getObject("flavors") - .getObject("newpipe") - - val versionName = newpipeVersionInfo.getString("version") - val versionCode = newpipeVersionInfo.getInt("version_code") - val apkLocationUrl = newpipeVersionInfo.getString("apk") - compareAppVersionAndShowNotification(versionName, apkLocationUrl, versionCode) + val jObj = JsonParser.`object`().from(response.responseBody()) + val versionName = jObj.getString("tag_name") + val apkLocationUrl = jObj + .getArray("assets") + .getObject(0) + .getString("browser_download_url") + compareAppVersionAndShowNotification(versionName, apkLocationUrl) } catch (e: JsonParserException) { - // Most likely something is wrong in data received from NEWPIPE_API_URL. - // Do not alarm user and fail silently. if (DEBUG) { - Log.w(TAG, "Could not get NewPipe API: invalid json", e) + Log.w(TAG, "Invalid json", e) } } } @@ -153,22 +140,9 @@ class NewVersionWorker( companion object { private val DEBUG = MainActivity.DEBUG private val TAG = NewVersionWorker::class.java.simpleName - private const val NEWPIPE_API_URL = "https://newpipe.net/api/data.json" + private const val NEWPIPE_API_URL = "https://api.github.com/repos/polymorphicshade/Tubular/releases/latest" private const val IS_MANUAL = "isManual" - /** - * Start a new worker which checks if all conditions for performing a version check are met, - * fetches the API endpoint [.NEWPIPE_API_URL] containing info about the latest NewPipe - * version and displays a notification about an available update if one is available. - *

- * Following conditions need to be met, before data is requested from the server: - * - * * The app is signed with the correct signing key (by TeamNewPipe / schabi). - * If the signing key differs from the one used upstream, the update cannot be installed. - * * The user enabled searching for and notifying about updates in the settings. - * * The app did not recently check for updates. - * We do not want to make unnecessary connections and DOS our servers. - */ @JvmStatic fun enqueueNewVersionCheckingWork(context: Context, isManual: Boolean) { val workRequest = OneTimeWorkRequestBuilder() diff --git a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java index 3776d78f6..a3b131d75 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java @@ -9,7 +9,6 @@ import androidx.annotation.NonNull; import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.R; -import org.schabi.newpipe.util.ReleaseVersionUtil; public class MainSettingsFragment extends BasePreferenceFragment { public static final boolean DEBUG = MainActivity.DEBUG; @@ -22,14 +21,6 @@ public class MainSettingsFragment extends BasePreferenceFragment { setHasOptionsMenu(true); // Otherwise onCreateOptionsMenu is not called - // Check if the app is updatable - if (!ReleaseVersionUtil.isReleaseApk()) { - getPreferenceScreen().removePreference( - findPreference(getString(R.string.update_pref_screen_key))); - - defaultPreferences.edit().putBoolean(getString(R.string.update_app_key), false).apply(); - } - // Hide debug preferences in RELEASE build variant if (!DEBUG) { getPreferenceScreen().removePreference( diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java index 3ee6668bf..00ee284ab 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java @@ -35,7 +35,6 @@ import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchResultListen import org.schabi.newpipe.settings.preferencesearch.PreferenceSearcher; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.KeyboardUtil; -import org.schabi.newpipe.util.ReleaseVersionUtil; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.views.FocusOverlayView; @@ -265,13 +264,6 @@ public class SettingsActivity extends AppCompatActivity implements * be found when searching inside a release. */ private void ensureSearchRepresentsApplicationState() { - // Check if the update settings are available - if (!ReleaseVersionUtil.isReleaseApk()) { - SettingsResourceRegistry.getInstance() - .getEntryByPreferencesResId(R.xml.update_settings) - .setSearchable(false); - } - // Hide debug preferences in RELEASE build variant if (DEBUG) { SettingsResourceRegistry.getInstance() diff --git a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt index 5a54b29d2..498b9f98a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt +++ b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt @@ -22,6 +22,7 @@ object ReleaseVersionUtil { private const val RELEASE_CERT_PUBLIC_KEY_SHA1 = "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15" + // TODO: no longer using this since this checks Github now... do we still need this? @JvmStatic fun isReleaseApk(): Boolean { return certificateSHA1Fingerprint == RELEASE_CERT_PUBLIC_KEY_SHA1 diff --git a/app/src/main/java/org/schabi/newpipe/util/Version.java b/app/src/main/java/org/schabi/newpipe/util/Version.java new file mode 100644 index 000000000..811aee1b7 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/Version.java @@ -0,0 +1,79 @@ +package org.schabi.newpipe.util; + +import android.util.Log; + +public final class Version implements Comparable { + private static final String TAG = Version.class.getSimpleName(); + private final int major; + private final int minor; + private final int build; + private final int rev; + + public Version(final int major, final int minor, final int build, final int rev) { + this.major = major; + this.minor = minor; + this.build = build; + this.rev = rev; + } + + public static Version fromString(final String str) { + // examples of valid version strings: + // - 0.1 + // - v0.1.0.4 + // - 0.20.6 + // - v0.20.6_r2 + try { + // example: v0.20.6_r2 -> v0.20.6.r2 -> 0.20.6.2 + final String[] split = str + .replaceAll("_", ".") + .replaceAll("[^0-9.]", "") + .split("[^\\d]"); + + final int major = Integer.parseInt(split[0]); + final int minor = split.length > 1 + ? Integer.parseInt(split[1]) + : 0; + final int build = split.length > 2 + ? Integer.parseInt(split[2]) + : 0; + final int rev = split.length > 3 + ? Integer.parseInt(split[3]) + : 0; + + return new Version(major, minor, build, rev); + } catch (final Exception e) { + Log.e(TAG, "Could not successfully parse version string.", e); + return new Version(0, 0, 0, 0); + } + } + + public int getMajor() { + return major; + } + + public int getMinor() { + return minor; + } + + public int getBuild() { + return build; + } + + public int getRev() { + return rev; + } + + @Override + public int compareTo(final Version that) { + if (this.getMajor() != that.getMajor()) { + return this.getMajor() < that.getMajor() ? -1 : 1; + } else if (this.getMinor() != that.getMinor()) { + return this.getMinor() < that.getMinor() ? -1 : 1; + } else if (this.getBuild() != that.getBuild()) { + return this.getBuild() < that.getBuild() ? -1 : 1; + } else if (this.getRev() != that.getRev()) { + return this.getRev() < that.getRev() ? -1 : 1; + } + return 0; + } +}