Merge pull request #6980 from bravenewpipe/check-for-update-after-toggle-and-restart

resets the expire date for checking for updates
This commit is contained in:
Tobi 2021-10-02 09:07:05 +02:00 committed by GitHub
commit ce592f4baf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 90 additions and 73 deletions

View File

@ -359,6 +359,9 @@
<service
android:name=".RouterActivity$FetcherService"
android:exported="false" />
<service
android:name=".CheckForNewAppVersion"
android:exported="false" />
<!-- opting out of sending metrics to Google in Android System WebView -->
<meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" />

View File

@ -5,7 +5,6 @@ import android.content.SharedPreferences;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.multidex.MultiDexApplication;
@ -37,7 +36,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
@ -45,6 +43,8 @@ import io.reactivex.rxjava3.exceptions.UndeliverableException;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
/*
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
* App.java is part of NewPipe.
@ -68,9 +68,6 @@ public class App extends MultiDexApplication {
private static final String TAG = App.class.toString();
private static App app;
@Nullable
private Disposable disposable = null;
@NonNull
public static App getApp() {
return app;
@ -118,14 +115,11 @@ public class App extends MultiDexApplication {
configureRxJavaErrorHandler();
// Check for new version
disposable = CheckForNewAppVersion.checkNewVersion(this);
startNewVersionCheckService();
}
@Override
public void onTerminate() {
if (disposable != null) {
disposable.dispose();
}
super.onTerminate();
PicassoHelper.terminate();
}

View File

@ -1,6 +1,7 @@
package org.schabi.newpipe;
import android.app.Application;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
@ -25,8 +26,11 @@ import com.grack.nanojson.JsonParserException;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -36,13 +40,10 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public final class CheckForNewAppVersion {
private CheckForNewAppVersion() { }
public final class CheckForNewAppVersion extends IntentService {
public CheckForNewAppVersion() {
super("CheckForNewAppVersion");
}
private static final boolean DEBUG = MainActivity.DEBUG;
private static final String TAG = CheckForNewAppVersion.class.getSimpleName();
@ -168,78 +169,87 @@ public final class CheckForNewAppVersion {
return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
}
@Nullable
public static Disposable checkNewVersion(@NonNull final App app) {
private void checkNewVersion() throws IOException, ReCaptchaException {
final App app = App.getApp();
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
final NewVersionManager manager = new NewVersionManager();
// Check if user has enabled/disabled update checking
// and if the current apk is a github one or not.
if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) {
return null;
return;
}
// Check if the last request has happened a certain time ago
// to reduce the number of API requests.
final long expiry = prefs.getLong(app.getString(R.string.update_expiry_key), 0);
if (!manager.isExpired(expiry)) {
return null;
return;
}
return Maybe
.fromCallable(() -> {
if (!isConnected(app)) {
return null;
}
// Make a network request to get latest NewPipe data.
final Response response = DownloaderImpl.getInstance().get(NEWPIPE_API_URL);
handleResponse(response, manager, prefs, app);
}
// Make a network request to get latest NewPipe data.
return DownloaderImpl.getInstance().get(NEWPIPE_API_URL);
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
response -> {
try {
// Store a timestamp which needs to be exceeded,
// before a new request to the API is made.
final long newExpiry = manager
.coerceExpiry(response.getHeader("expires"));
prefs.edit()
.putLong(app.getString(R.string.update_expiry_key), newExpiry)
.apply();
} catch (final Exception e) {
if (DEBUG) {
Log.w(TAG, "Could not extract and save new expiry date", e);
}
}
private void handleResponse(@NonNull final Response response,
@NonNull final NewVersionManager manager,
@NonNull final SharedPreferences prefs,
@NonNull final App app) {
try {
// Store a timestamp which needs to be exceeded,
// before a new request to the API is made.
final long newExpiry = manager
.coerceExpiry(response.getHeader("expires"));
prefs.edit()
.putLong(app.getString(R.string.update_expiry_key), newExpiry)
.apply();
} catch (final Exception e) {
if (DEBUG) {
Log.w(TAG, "Could not extract and save new expiry date", e);
}
}
// Parse the json from the response.
try {
final JsonObject githubStableObject = JsonParser.object()
.from(response.responseBody()).getObject("flavors")
.getObject("github").getObject("stable");
// Parse the json from the response.
try {
final JsonObject githubStableObject = JsonParser.object()
.from(response.responseBody()).getObject("flavors")
.getObject("github").getObject("stable");
final String versionName = githubStableObject
.getString("version");
final int versionCode = githubStableObject
.getInt("version_code");
final String apkLocationUrl = githubStableObject
.getString("apk");
final String versionName = githubStableObject
.getString("version");
final int versionCode = githubStableObject
.getInt("version_code");
final String apkLocationUrl = githubStableObject
.getString("apk");
compareAppVersionAndShowNotification(app, versionName,
apkLocationUrl, versionCode);
} catch (final JsonParserException e) {
// 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);
}
}
}
public static void startNewVersionCheckService() {
final Intent intent = new Intent(App.getApp().getApplicationContext(),
CheckForNewAppVersion.class);
App.getApp().startService(intent);
}
@Override
protected void onHandleIntent(@Nullable final Intent intent) {
try {
checkNewVersion();
} catch (final IOException e) {
Log.w(TAG, "Could not fetch NewPipe API: probably network problem", e);
} catch (final ReCaptchaException e) {
Log.e(TAG, "ReCaptchaException should never happen here.", e);
}
compareAppVersionAndShowNotification(app, versionName,
apkLocationUrl, versionCode);
} catch (final JsonParserException e) {
// connectivity problems, do not alarm user and fail silently
if (DEBUG) {
Log.w(TAG, "Could not get NewPipe API: invalid json", e);
}
}
},
e -> {
// connectivity problems, do not alarm user and fail silently
if (DEBUG) {
Log.w(TAG, "Could not get NewPipe API: network problem", e);
}
});
}
}

View File

@ -6,11 +6,21 @@ import androidx.preference.Preference;
import org.schabi.newpipe.R;
import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
public class UpdateSettingsFragment extends BasePreferenceFragment {
private final Preference.OnPreferenceChangeListener updatePreferenceChange
= (preference, newValue) -> {
= (preference, checkForUpdates) -> {
defaultPreferences.edit()
.putBoolean(getString(R.string.update_app_key), (boolean) newValue).apply();
.putBoolean(getString(R.string.update_app_key), (boolean) checkForUpdates).apply();
if ((boolean) checkForUpdates) {
// Search for updates immediately when update checks are enabled.
// Reset the expire time. This is necessary to check for an update immediately.
defaultPreferences.edit()
.putLong(getString(R.string.update_expiry_key), 0).apply();
startNewVersionCheckService();
}
return true;
};