mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Ask for consent before starting update checks
NewPipe is contacting its servers without asking for the users' consent. This is categorized as "tracking" by F-Droid (see https://github.com/TeamNewPipe/NewPipe/discussions/10785). This commit disables checking for udpates by default and adds a dialog asking for the user's consent to automatically check for updates if the app version is eligible for them. After upgrading to a version containing this commit the user is asked directly on the first app start. On fresh installs however, showing it on the first app start contributes to a bad onboarding an welcoming experience. Therefore, the dialog is shown at the second app start. Co-authored-by: Stypox <stypox@pm.me>
This commit is contained in:
		| @@ -60,6 +60,8 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins; | ||||
| public class App extends Application { | ||||
|     public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID; | ||||
|     private static final String TAG = App.class.toString(); | ||||
|  | ||||
|     private boolean isFirstRun = false; | ||||
|     private static App app; | ||||
|  | ||||
|     @NonNull | ||||
| @@ -85,7 +87,13 @@ public class App extends Application { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Initialize settings first because others inits can use its values | ||||
|         // check if the last used preference version is set | ||||
|         // to determine whether this is the first app run | ||||
|         final int lastUsedPrefVersion = PreferenceManager.getDefaultSharedPreferences(this) | ||||
|                 .getInt(getString(R.string.last_used_preferences_version), -1); | ||||
|         isFirstRun = lastUsedPrefVersion == -1; | ||||
|  | ||||
|         // Initialize settings first because other initializations can use its values | ||||
|         NewPipeSettings.initSettings(this); | ||||
|  | ||||
|         NewPipe.init(getDownloader(), | ||||
| @@ -255,4 +263,7 @@ public class App extends Application { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public boolean isFirstRun() { | ||||
|         return isFirstRun; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -79,6 +79,7 @@ import org.schabi.newpipe.player.Player; | ||||
| import org.schabi.newpipe.player.event.OnKeyDownListener; | ||||
| import org.schabi.newpipe.player.helper.PlayerHolder; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueue; | ||||
| import org.schabi.newpipe.settings.UpdateSettingsFragment; | ||||
| import org.schabi.newpipe.util.Constants; | ||||
| import org.schabi.newpipe.util.DeviceUtils; | ||||
| import org.schabi.newpipe.util.KioskTranslator; | ||||
| @@ -86,6 +87,7 @@ import org.schabi.newpipe.util.Localization; | ||||
| import org.schabi.newpipe.util.NavigationHelper; | ||||
| import org.schabi.newpipe.util.PeertubeHelper; | ||||
| import org.schabi.newpipe.util.PermissionHelper; | ||||
| import org.schabi.newpipe.util.ReleaseVersionUtil; | ||||
| import org.schabi.newpipe.util.SerializedCache; | ||||
| import org.schabi.newpipe.util.ServiceHelper; | ||||
| import org.schabi.newpipe.util.StateSaver; | ||||
| @@ -167,6 +169,11 @@ public class MainActivity extends AppCompatActivity { | ||||
|             // if this is enabled by the user. | ||||
|             NotificationWorker.initialize(this); | ||||
|         } | ||||
|         if (!UpdateSettingsFragment.wasUserAskedForConsent(this) | ||||
|                 && ReleaseVersionUtil.INSTANCE.isReleaseApk() | ||||
|                 && !App.getApp().isFirstRun()) { | ||||
|             UpdateSettingsFragment.askForConsentToUpdateChecks(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -11,6 +11,7 @@ import androidx.annotation.NonNull; | ||||
| import androidx.annotation.StringRes; | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | ||||
| import org.schabi.newpipe.App; | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.util.DeviceUtils; | ||||
|  | ||||
| @@ -44,14 +45,8 @@ public final class NewPipeSettings { | ||||
|     private NewPipeSettings() { } | ||||
|  | ||||
|     public static void initSettings(final Context context) { | ||||
|         // check if the last used preference version is set | ||||
|         // to determine whether this is the first app run | ||||
|         final int lastUsedPrefVersion = PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getInt(context.getString(R.string.last_used_preferences_version), -1); | ||||
|         final boolean isFirstRun = lastUsedPrefVersion == -1; | ||||
|  | ||||
|         // first run migrations, then setDefaultValues, since the latter requires the correct types | ||||
|         SettingMigrations.runMigrationsIfNeeded(context, isFirstRun); | ||||
|         SettingMigrations.runMigrationsIfNeeded(context); | ||||
|  | ||||
|         // readAgain is true so that if new settings are added their default value is set | ||||
|         PreferenceManager.setDefaultValues(context, R.xml.main_settings, true); | ||||
| @@ -68,7 +63,7 @@ public final class NewPipeSettings { | ||||
|         saveDefaultVideoDownloadDirectory(context); | ||||
|         saveDefaultAudioDownloadDirectory(context); | ||||
|  | ||||
|         disableMediaTunnelingIfNecessary(context, isFirstRun); | ||||
|         disableMediaTunnelingIfNecessary(context); | ||||
|     } | ||||
|  | ||||
|     static void saveDefaultVideoDownloadDirectory(final Context context) { | ||||
| @@ -146,8 +141,7 @@ public final class NewPipeSettings { | ||||
|                 R.string.show_remote_search_suggestions_key); | ||||
|     } | ||||
|  | ||||
|     private static void disableMediaTunnelingIfNecessary(@NonNull final Context context, | ||||
|                                                          final boolean isFirstRun) { | ||||
|     private static void disableMediaTunnelingIfNecessary(@NonNull final Context context) { | ||||
|         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | ||||
|         final String disabledTunnelingKey = context.getString(R.string.disable_media_tunneling_key); | ||||
|         final String disabledTunnelingAutomaticallyKey = | ||||
| @@ -162,7 +156,7 @@ public final class NewPipeSettings { | ||||
|                 prefs.getInt(disabledTunnelingAutomaticallyKey, -1) == 0 | ||||
|                         && !prefs.getBoolean(disabledTunnelingKey, false); | ||||
|  | ||||
|         if (Boolean.TRUE.equals(isFirstRun) | ||||
|         if (App.getApp().isFirstRun() | ||||
|                 || (wasDeviceBlacklistUpdated && !wasMediaTunnelingEnabledByUser)) { | ||||
|             setMediaTunneling(context); | ||||
|         } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import android.util.Log; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | ||||
| import org.schabi.newpipe.App; | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.error.ErrorInfo; | ||||
| import org.schabi.newpipe.error.ErrorUtil; | ||||
| @@ -163,15 +164,14 @@ public final class SettingMigrations { | ||||
|     private static final int VERSION = 6; | ||||
|  | ||||
|  | ||||
|     public static void runMigrationsIfNeeded(@NonNull final Context context, | ||||
|                                              final boolean isFirstRun) { | ||||
|     public static void runMigrationsIfNeeded(@NonNull final Context context) { | ||||
|         // setup migrations and check if there is something to do | ||||
|         sp = PreferenceManager.getDefaultSharedPreferences(context); | ||||
|         final String lastPrefVersionKey = context.getString(R.string.last_used_preferences_version); | ||||
|         final int lastPrefVersion = sp.getInt(lastPrefVersionKey, 0); | ||||
|  | ||||
|         // no migration to run, already up to date | ||||
|         if (isFirstRun) { | ||||
|         if (App.getApp().isFirstRun()) { | ||||
|             sp.edit().putInt(lastPrefVersionKey, VERSION).apply(); | ||||
|             return; | ||||
|         } else if (lastPrefVersion == VERSION) { | ||||
|   | ||||
| @@ -1,9 +1,12 @@ | ||||
| package org.schabi.newpipe.settings; | ||||
|  | ||||
| import android.app.AlertDialog; | ||||
| import android.content.Context; | ||||
| import android.os.Bundle; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.preference.Preference; | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | ||||
| import org.schabi.newpipe.NewVersionWorker; | ||||
| import org.schabi.newpipe.R; | ||||
| @@ -36,4 +39,38 @@ public class UpdateSettingsFragment extends BasePreferenceFragment { | ||||
|         findPreference(getString(R.string.manual_update_key)) | ||||
|                 .setOnPreferenceClickListener(manualUpdateClick); | ||||
|     } | ||||
|  | ||||
|     public static void askForConsentToUpdateChecks(final Context context) { | ||||
|         new AlertDialog.Builder(context) | ||||
|                 .setTitle(context.getString(R.string.check_for_updates)) | ||||
|                 .setMessage(context.getString(R.string.auto_update_check_description)) | ||||
|                 .setPositiveButton(context.getString(R.string.yes), (d, w) -> { | ||||
|                     d.dismiss(); | ||||
|                     setAutoUpdateCheckEnabled(context, true); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.no, (d, w) -> { | ||||
|                     d.dismiss(); | ||||
|                     // set explicitly to false, since the default is true on previous versions | ||||
|                     setAutoUpdateCheckEnabled(context, false); | ||||
|                 }) | ||||
|                 .show(); | ||||
|     } | ||||
|  | ||||
|     private static void setAutoUpdateCheckEnabled(final Context context, final boolean enabled) { | ||||
|         PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .edit() | ||||
|                 .putBoolean(context.getString(R.string.update_app_key), enabled) | ||||
|                 .putBoolean(context.getString(R.string.update_check_consent_key), true) | ||||
|                 .apply(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Whether the user was asked for consent to automatically check for app updates. | ||||
|      * @param context | ||||
|      * @return true if the user was asked for consent, false otherwise | ||||
|      */ | ||||
|     public static boolean wasUserAskedForConsent(final Context context) { | ||||
|         return PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getBoolean(context.getString(R.string.update_check_consent_key), false); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -494,6 +494,7 @@ | ||||
|     </string-array> | ||||
|  | ||||
|     <!-- Updates --> | ||||
|     <string name="update_check_consent_key">update_check_consent_key</string> | ||||
|     <string name="update_app_key">update_app_key</string> | ||||
|     <string name="manual_update_key">manual_update_key</string> | ||||
|     <string name="update_pref_screen_key">update_pref_screen_key</string> | ||||
|   | ||||
| @@ -7,6 +7,8 @@ | ||||
|     <string name="install">Install</string> | ||||
|     <string name="cancel">Cancel</string> | ||||
|     <string name="ok">OK</string> | ||||
|     <string name="yes">Yes</string> | ||||
|     <string name="no">No</string> | ||||
|     <string name="open_in_browser">Open in browser</string> | ||||
|     <string name="mark_as_watched">Mark as watched</string> | ||||
|     <string name="open_in_popup_mode">Open in popup mode</string> | ||||
| @@ -557,8 +559,10 @@ | ||||
|     <string name="updates_setting_title">Updates</string> | ||||
|     <string name="updates_setting_description">Show a notification to prompt app update when a new version is available</string> | ||||
|     <string name="check_for_updates">Check for updates</string> | ||||
|     <string name="auto_update_check_description">NewPipe can automatically check for new versions from time to time and notify you once they are available.\nDo you want to enable this?</string> | ||||
|     <string name="manual_update_title" translatable="false">@string/check_for_updates</string> | ||||
|     <string name="manual_update_description">Manually check for new versions</string> | ||||
|  | ||||
|     <!-- Minimize to exit action --> | ||||
|     <string name="minimize_on_exit_title">Minimize on app switch</string> | ||||
|     <string name="minimize_on_exit_summary">Action when switching to other app from main video player — %s</string> | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     android:title="@string/settings_category_updates_title"> | ||||
|  | ||||
|     <SwitchPreferenceCompat | ||||
|         android:defaultValue="true" | ||||
|         android:defaultValue="false" | ||||
|         android:key="@string/update_app_key" | ||||
|         android:summary="@string/updates_setting_description" | ||||
|         android:title="@string/updates_setting_title" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tobi
					Tobi