1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-12-23 16:40:32 +00:00

Merge pull request #4948 from Stypox/fix-crash-startup

Fix crash on startup when there is no internet connection
This commit is contained in:
Tobias Groza 2020-11-22 14:00:36 +01:00 committed by GitHub
commit c88b4032ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 62 deletions

View File

@ -8,6 +8,7 @@ import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.multidex.MultiDexApplication; import androidx.multidex.MultiDexApplication;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
@ -67,7 +68,7 @@ public class App extends MultiDexApplication {
protected static final String TAG = App.class.toString(); protected static final String TAG = App.class.toString();
private static App app; private static App app;
private Disposable disposable = null; @Nullable private Disposable disposable = null;
@NonNull @NonNull
public static App getApp() { public static App getApp() {

View File

@ -12,6 +12,7 @@ import android.net.Uri;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -21,13 +22,11 @@ import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException; import com.grack.nanojson.JsonParserException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo; import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -36,10 +35,9 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import io.reactivex.Observable; import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.disposables.Disposables;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
public final class CheckForNewAppVersion { public final class CheckForNewAppVersion {
@ -58,48 +56,43 @@ public final class CheckForNewAppVersion {
* @param application The application * @param application The application
* @return String with the apk's SHA1 fingeprint in hexadecimal * @return String with the apk's SHA1 fingeprint in hexadecimal
*/ */
@NonNull
private static String getCertificateSHA1Fingerprint(@NonNull final Application application) { private static String getCertificateSHA1Fingerprint(@NonNull final Application application) {
final PackageManager pm = application.getPackageManager(); final PackageInfo packageInfo;
final String packageName = application.getPackageName();
final int flags = PackageManager.GET_SIGNATURES;
PackageInfo packageInfo = null;
try { try {
packageInfo = pm.getPackageInfo(packageName, flags); packageInfo = application.getPackageManager().getPackageInfo(
application.getPackageName(), PackageManager.GET_SIGNATURES);
} catch (final PackageManager.NameNotFoundException e) { } catch (final PackageManager.NameNotFoundException e) {
ErrorActivity.reportError(application, e, null, null, ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Could not find package info", R.string.app_ui_crash)); "Could not find package info", R.string.app_ui_crash));
return "";
} }
final X509Certificate c;
try {
final Signature[] signatures = packageInfo.signatures; final Signature[] signatures = packageInfo.signatures;
final byte[] cert = signatures[0].toByteArray(); final byte[] cert = signatures[0].toByteArray();
final InputStream input = new ByteArrayInputStream(cert); final InputStream input = new ByteArrayInputStream(cert);
X509Certificate c = null;
try {
final CertificateFactory cf = CertificateFactory.getInstance("X509"); final CertificateFactory cf = CertificateFactory.getInstance("X509");
c = (X509Certificate) cf.generateCertificate(input); c = (X509Certificate) cf.generateCertificate(input);
} catch (final CertificateException e) { } catch (final CertificateException e) {
ErrorActivity.reportError(application, e, null, null, ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Certificate error", R.string.app_ui_crash)); "Certificate error", R.string.app_ui_crash));
return "";
} }
String hexString = null;
try { try {
final MessageDigest md = MessageDigest.getInstance("SHA1"); final MessageDigest md = MessageDigest.getInstance("SHA1");
final byte[] publicKey = md.digest(c.getEncoded()); final byte[] publicKey = md.digest(c.getEncoded());
hexString = byte2HexFormatted(publicKey); return byte2HexFormatted(publicKey);
} catch (NoSuchAlgorithmException | CertificateEncodingException e) { } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
ErrorActivity.reportError(application, e, null, null, ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none", ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Could not retrieve SHA1 key", R.string.app_ui_crash)); "Could not retrieve SHA1 key", R.string.app_ui_crash));
return "";
} }
return hexString;
} }
private static String byte2HexFormatted(final byte[] arr) { private static String byte2HexFormatted(final byte[] arr) {
@ -164,65 +157,65 @@ public final class CheckForNewAppVersion {
} }
private static boolean isConnected(@NonNull final App app) { private static boolean isConnected(@NonNull final App app) {
final ConnectivityManager cm = ContextCompat.getSystemService(app, final ConnectivityManager connectivityManager =
ConnectivityManager.class); ContextCompat.getSystemService(app, ConnectivityManager.class);
return cm.getActiveNetworkInfo() != null return connectivityManager != null && connectivityManager.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnected(); && connectivityManager.getActiveNetworkInfo().isConnected();
} }
public static boolean isGithubApk(@NonNull final App app) { public static boolean isGithubApk(@NonNull final App app) {
return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1); return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
} }
@NonNull @Nullable
public static Disposable checkNewVersion(@NonNull final App app) { public static Disposable checkNewVersion(@NonNull final App app) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
// Check if user has enabled/disabled update checking // Check if user has enabled/disabled update checking
// and if the current apk is a github one or not. // and if the current apk is a github one or not.
if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) {
|| !isGithubApk(app)) { return null;
return Disposables.empty();
} }
return Observable.fromCallable(() -> { return Maybe
.fromCallable(() -> {
if (!isConnected(app)) { if (!isConnected(app)) {
return null; return null;
} }
// Make a network request to get latest NewPipe data. // Make a network request to get latest NewPipe data.
try {
return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody(); 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()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> { .subscribe(
response -> {
// Parse the json from the response. // Parse the json from the response.
if (response != null) {
try { try {
final JsonObject githubStableObject = JsonParser.object().from(response) final JsonObject githubStableObject = JsonParser.object()
.getObject("flavors").getObject("github").getObject("stable"); .from(response).getObject("flavors").getObject("github")
.getObject("stable");
final String versionName = githubStableObject.getString("version"); final String versionName = githubStableObject
final int versionCode = githubStableObject.getInt("version_code"); .getString("version");
final String apkLocationUrl = githubStableObject.getString("apk"); final int versionCode = githubStableObject
.getInt("version_code");
final String apkLocationUrl = githubStableObject
.getString("apk");
compareAppVersionAndShowNotification(app, versionName, apkLocationUrl, compareAppVersionAndShowNotification(app, versionName,
versionCode); apkLocationUrl, versionCode);
} catch (final JsonParserException e) { } catch (final JsonParserException e) {
// connectivity problems, do not alarm user and fail silently // connectivity problems, do not alarm user and fail silently
if (DEBUG) { if (DEBUG) {
Log.w(TAG, Log.getStackTraceString(e)); 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);
} }
}); });
} }