From 8dc4e6dc2ad692d4ba56f88513f652c5f110a454 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 21 Nov 2020 11:38:08 +0100 Subject: [PATCH 1/4] Fix crash on startup without internet: Cbservable callable returning null Use Maybe instead --- app/src/main/java/org/schabi/newpipe/App.java | 3 +- .../schabi/newpipe/CheckForNewAppVersion.java | 69 +++++++++---------- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 51d0f1016..5348db115 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -8,6 +8,7 @@ import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.multidex.MultiDexApplication; import androidx.preference.PreferenceManager; @@ -67,7 +68,7 @@ public class App extends MultiDexApplication { protected static final String TAG = App.class.toString(); private static App app; - private Disposable disposable = null; + @Nullable private Disposable disposable = null; @NonNull public static App getApp() { diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java index 1bec52dcd..4221b9ee8 100644 --- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java +++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java @@ -12,6 +12,7 @@ import android.net.Uri; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; @@ -36,10 +37,9 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import io.reactivex.Observable; +import io.reactivex.Maybe; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; -import io.reactivex.disposables.Disposables; import io.reactivex.schedulers.Schedulers; public final class CheckForNewAppVersion { @@ -174,54 +174,51 @@ public final class CheckForNewAppVersion { return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1); } - @NonNull + @Nullable public static Disposable checkNewVersion(@NonNull final App app) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app); // 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 Disposables.empty(); + if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) { + return null; } - return Observable.fromCallable(() -> { - if (!isConnected(app)) { - return null; - } + return Maybe + .fromCallable(() -> { + if (!isConnected(app)) { + return null; + } - // Make a network request to get latest NewPipe data. - try { - return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody(); - } catch (IOException | ReCaptchaException e) { - // connectivity problems, do not alarm user and fail silently - if (DEBUG) { - Log.w(TAG, Log.getStackTraceString(e)); - } - } - - return null; - }) + // Make a network request to get latest NewPipe data. + try { + return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody(); + } catch (IOException | ReCaptchaException e) { + // connectivity problems, do not alarm user and fail silently + if (DEBUG) { + Log.w(TAG, Log.getStackTraceString(e)); + } + return null; + } + }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(response -> { // Parse the json from the response. - if (response != null) { - try { - final JsonObject githubStableObject = JsonParser.object().from(response) - .getObject("flavors").getObject("github").getObject("stable"); + try { + final JsonObject githubStableObject = JsonParser.object().from(response) + .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) { - // connectivity problems, do not alarm user and fail silently - if (DEBUG) { - Log.w(TAG, Log.getStackTraceString(e)); - } + compareAppVersionAndShowNotification(app, versionName, apkLocationUrl, + versionCode); + } catch (final JsonParserException e) { + // connectivity problems, do not alarm user and fail silently + if (DEBUG) { + Log.w(TAG, Log.getStackTraceString(e)); } } }); From 17866c29aea4b17771faf2d81671bd2de2d9bdca Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 21 Nov 2020 11:43:57 +0100 Subject: [PATCH 2/4] Refactor CheckForNewAppVersion --- .../schabi/newpipe/CheckForNewAppVersion.java | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java index 4221b9ee8..f9b18d463 100644 --- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java +++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java @@ -58,48 +58,43 @@ public final class CheckForNewAppVersion { * @param application The application * @return String with the apk's SHA1 fingeprint in hexadecimal */ + @NonNull private static String getCertificateSHA1Fingerprint(@NonNull final Application application) { - final PackageManager pm = application.getPackageManager(); - final String packageName = application.getPackageName(); - final int flags = PackageManager.GET_SIGNATURES; - PackageInfo packageInfo = null; - + final PackageInfo packageInfo; try { - packageInfo = pm.getPackageInfo(packageName, flags); + packageInfo = application.getPackageManager().getPackageInfo( + application.getPackageName(), PackageManager.GET_SIGNATURES); } catch (final PackageManager.NameNotFoundException e) { ErrorActivity.reportError(application, e, null, null, ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", "Could not find package info", R.string.app_ui_crash)); + return ""; } - final Signature[] signatures = packageInfo.signatures; - final byte[] cert = signatures[0].toByteArray(); - final InputStream input = new ByteArrayInputStream(cert); - - X509Certificate c = null; - + final X509Certificate c; try { + final Signature[] signatures = packageInfo.signatures; + final byte[] cert = signatures[0].toByteArray(); + final InputStream input = new ByteArrayInputStream(cert); final CertificateFactory cf = CertificateFactory.getInstance("X509"); c = (X509Certificate) cf.generateCertificate(input); } catch (final CertificateException e) { ErrorActivity.reportError(application, e, null, null, ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", "Certificate error", R.string.app_ui_crash)); + return ""; } - String hexString = null; - try { final MessageDigest md = MessageDigest.getInstance("SHA1"); final byte[] publicKey = md.digest(c.getEncoded()); - hexString = byte2HexFormatted(publicKey); + return byte2HexFormatted(publicKey); } catch (NoSuchAlgorithmException | CertificateEncodingException e) { ErrorActivity.reportError(application, e, null, null, ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", "Could not retrieve SHA1 key", R.string.app_ui_crash)); + return ""; } - - return hexString; } private static String byte2HexFormatted(final byte[] arr) { @@ -164,10 +159,10 @@ public final class CheckForNewAppVersion { } private static boolean isConnected(@NonNull final App app) { - final ConnectivityManager cm = ContextCompat.getSystemService(app, - ConnectivityManager.class); - return cm.getActiveNetworkInfo() != null - && cm.getActiveNetworkInfo().isConnected(); + final ConnectivityManager connectivityManager = + ContextCompat.getSystemService(app, ConnectivityManager.class); + return connectivityManager != null && connectivityManager.getActiveNetworkInfo() != null + && connectivityManager.getActiveNetworkInfo().isConnected(); } public static boolean isGithubApk(@NonNull final App app) { From fd4c37e9b38c1f75f6e91d6e9cc1137890223c6c Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 22 Nov 2020 11:46:19 +0100 Subject: [PATCH 3/4] Fix crash on startup caused by no implementation of onError() method --- .../schabi/newpipe/CheckForNewAppVersion.java | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java index f9b18d463..b18445ab5 100644 --- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java +++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java @@ -198,24 +198,36 @@ public final class CheckForNewAppVersion { }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(response -> { - // Parse the json from the response. - try { - final JsonObject githubStableObject = JsonParser.object().from(response) - .getObject("flavors").getObject("github").getObject("stable"); + .subscribe( + response -> { + // Parse the json from the response. + try { + final JsonObject githubStableObject = JsonParser.object() + .from(response).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) { - // connectivity problems, do not alarm user and fail silently - if (DEBUG) { - Log.w(TAG, Log.getStackTraceString(e)); - } - } - }); + compareAppVersionAndShowNotification(app, versionName, + apkLocationUrl, versionCode); + } catch (final JsonParserException e) { + // connectivity problems, do not alarm user and fail silently + if (DEBUG) { + Log.w(TAG, Log.getStackTraceString(e)); + } + } + }, + throwable -> { + // connectivity problems, do not alarm user and fail silently + if (DEBUG) { + Log.i(TAG, "Could not get NewPipe API: network problem"); + Log.i(TAG, Log.getStackTraceString(throwable)); + } + }); } } From 6f5e99be6fa382ef40ddec3529f7fcf86e0ca0c8 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 22 Nov 2020 13:27:51 +0100 Subject: [PATCH 4/4] Handle CheckForNewAppVersion exceptions in one place --- .../schabi/newpipe/CheckForNewAppVersion.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java index b18445ab5..661337b28 100644 --- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java +++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java @@ -22,13 +22,11 @@ import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParserException; -import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorInfo; import org.schabi.newpipe.report.UserAction; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -186,15 +184,7 @@ public final class CheckForNewAppVersion { } // Make a network request to get latest NewPipe data. - try { - return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody(); - } catch (IOException | ReCaptchaException e) { - // connectivity problems, do not alarm user and fail silently - if (DEBUG) { - Log.w(TAG, Log.getStackTraceString(e)); - } - return null; - } + return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -218,15 +208,14 @@ public final class CheckForNewAppVersion { } catch (final JsonParserException e) { // connectivity problems, do not alarm user and fail silently if (DEBUG) { - Log.w(TAG, Log.getStackTraceString(e)); + Log.w(TAG, "Could not get NewPipe API: invalid json", e); } } }, - throwable -> { + e -> { // connectivity problems, do not alarm user and fail silently if (DEBUG) { - Log.i(TAG, "Could not get NewPipe API: network problem"); - Log.i(TAG, Log.getStackTraceString(throwable)); + Log.w(TAG, "Could not get NewPipe API: network problem", e); } }); }