mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Add migration concept for shared preferences
This commit is contained in:
		| @@ -20,7 +20,8 @@ public enum UserAction { | ||||
|     DELETE_FROM_HISTORY("delete from history"), | ||||
|     PLAY_STREAM("Play stream"), | ||||
|     DOWNLOAD_POSTPROCESSING("download post-processing"), | ||||
|     DOWNLOAD_FAILED("download failed"); | ||||
|     DOWNLOAD_FAILED("download failed"), | ||||
|     PREFERENCES_MIGRATION("migration of preferences"); | ||||
|  | ||||
|  | ||||
|     private final String message; | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import androidx.preference.PreferenceManager; | ||||
| import org.schabi.newpipe.R; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.util.Set; | ||||
|  | ||||
| /* | ||||
|  * Created by k3b on 07.01.2016. | ||||
| @@ -38,6 +39,22 @@ public final class NewPipeSettings { | ||||
|     private NewPipeSettings() { } | ||||
|  | ||||
|     public static void initSettings(final Context context) { | ||||
|         // check if there are entries in the prefs to determine whether this is the first app run | ||||
|         Boolean isFirstRun = null; | ||||
|         final Set<String> prefsKeys = PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getAll().keySet(); | ||||
|         for (final String key: prefsKeys) { | ||||
|             // ACRA stores some info in the prefs during app initialization | ||||
|             // which happens before this method is called. Therefore ignore ACRA-related keys. | ||||
|             if (!key.toLowerCase().startsWith("acra")) { | ||||
|                 isFirstRun = false; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (isFirstRun == null) { | ||||
|             isFirstRun = true; | ||||
|         } | ||||
|  | ||||
|         PreferenceManager.setDefaultValues(context, R.xml.appearance_settings, true); | ||||
|         PreferenceManager.setDefaultValues(context, R.xml.content_settings, true); | ||||
|         PreferenceManager.setDefaultValues(context, R.xml.download_settings, true); | ||||
| @@ -48,6 +65,8 @@ public final class NewPipeSettings { | ||||
|  | ||||
|         getVideoDownloadFolder(context); | ||||
|         getAudioDownloadFolder(context); | ||||
|  | ||||
|         SettingMigrations.initMigrations(context, isFirstRun); | ||||
|     } | ||||
|  | ||||
|     private static void getVideoDownloadFolder(final Context context) { | ||||
|   | ||||
| @@ -0,0 +1,106 @@ | ||||
| package org.schabi.newpipe.settings; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.util.Log; | ||||
|  | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.report.ErrorActivity; | ||||
| import org.schabi.newpipe.report.ErrorActivity.ErrorInfo; | ||||
| import org.schabi.newpipe.report.UserAction; | ||||
|  | ||||
| import static org.schabi.newpipe.MainActivity.DEBUG; | ||||
|  | ||||
| public final class SettingMigrations { | ||||
|     private static final String TAG = SettingMigrations.class.toString(); | ||||
|     /** | ||||
|      * Version number for preferences. Must be incremented every time a migration is necessary. | ||||
|      */ | ||||
|     public static final int VERSION = 0; | ||||
|     private static SharedPreferences sp; | ||||
|  | ||||
|     /** | ||||
|      * List of all implemented migrations. | ||||
|      * <p> | ||||
|      * <b>Append new migrations to the end of the list</b> to keep it sorted ascending. | ||||
|      * If not sorted correctly, migrations which depend on each other, may fail. | ||||
|      */ | ||||
|     private static final Migration[] SETTING_MIGRATIONS = { | ||||
|  | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     public static void initMigrations(final Context context, final boolean isFirstRun) { | ||||
|         // 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) { | ||||
|             sp.edit().putInt(lastPrefVersionKey, VERSION).apply(); | ||||
|             return; | ||||
|         } else if (lastPrefVersion == VERSION) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // run migrations | ||||
|         int currentVersion = lastPrefVersion; | ||||
|         for (final Migration currentMigration : SETTING_MIGRATIONS) { | ||||
|             try { | ||||
|                 if (currentMigration.shouldMigrate(currentVersion)) { | ||||
|                     if (DEBUG) { | ||||
|                         Log.d(TAG, "Migrating preferences from version " | ||||
|                                 + currentVersion + " to " + currentMigration.newVersion); | ||||
|                     } | ||||
|                     currentMigration.migrate(context); | ||||
|                     currentVersion = currentMigration.newVersion; | ||||
|                 } | ||||
|             } catch (final Exception e) { | ||||
|                 // save the version with the last successful migration and report the error | ||||
|                 sp.edit().putInt(lastPrefVersionKey, currentVersion).apply(); | ||||
|                 final ErrorInfo errorInfo = ErrorInfo.make( | ||||
|                         UserAction.PREFERENCES_MIGRATION, | ||||
|                         "none", | ||||
|                         "Migrating preferences from version " + lastPrefVersion + " to " | ||||
|                                 + VERSION + ". " | ||||
|                                 + "Error at " + currentVersion  + " => " + ++currentVersion, | ||||
|                         0 | ||||
|                 ); | ||||
|                 ErrorActivity.reportError(context, e, SettingMigrations.class, null, errorInfo); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // store the current preferences version | ||||
|         sp.edit().putInt(lastPrefVersionKey, currentVersion).apply(); | ||||
|     } | ||||
|  | ||||
|     private SettingMigrations() { } | ||||
|  | ||||
|     abstract static class Migration { | ||||
|         public final int oldVersion; | ||||
|         public final int newVersion; | ||||
|  | ||||
|         protected Migration(final int oldVersion, final int newVersion) { | ||||
|             this.oldVersion = oldVersion; | ||||
|             this.newVersion = newVersion; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @param currentVersion current settings version | ||||
|          * @return Returns whether this migration should be run. | ||||
|          * A migration is necessary if the old version of this migration is lower than or equal to | ||||
|          * the current settings version. | ||||
|          */ | ||||
|         private boolean shouldMigrate(final int currentVersion) { | ||||
|             return oldVersion >= currentVersion; | ||||
|         } | ||||
|  | ||||
|         protected abstract void migrate(Context context); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,9 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources translatable="false"> | ||||
|     <!-- App versioning --> | ||||
|     <string name="last_used_version" translatable="false">last_used_version</string> | ||||
|     <string name="last_used_preferences_version" translatable="false">last_used_preferences_version</string> | ||||
|  | ||||
|     <!-- Service --> | ||||
|     <string-array name="service_list" translatable="false"> | ||||
|         <item>@string/youtube</item> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 TobiGr
					TobiGr