Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e772224
update List<String> encode/decode and other simple breaking changes
tarrinneal Dec 20, 2024
089d11d
fix test set up and legacy android system
tarrinneal Jan 2, 2025
29f3662
Merge branch 'main' of github.com:flutter/packages into listString-en…
tarrinneal Jan 2, 2025
c0c08df
format analyze update to latest pigeon
tarrinneal Jan 3, 2025
2ef0a01
remove unneeded braces from switch statement
tarrinneal Jan 3, 2025
bad5268
revert all breaking changes
tarrinneal Jan 6, 2025
7a013b1
Merge branch 'main' of github.com:flutter/packages into listString-en…
tarrinneal Jan 6, 2025
2c10fb7
rest of the comments
tarrinneal Jan 6, 2025
614cbe4
update test getter to match setter
tarrinneal Jan 6, 2025
e622f04
fix tests that I broke fixing tests
tarrinneal Jan 7, 2025
d317354
fix android code for error handling changes reversion
tarrinneal Jan 7, 2025
79ebe43
split getList and other nits
tarrinneal Jan 14, 2025
3a45c25
Merge branch 'main' of github.com:flutter/packages into listString-en…
tarrinneal Jan 14, 2025
a49fb9f
add new method to kotlin class
tarrinneal Jan 16, 2025
e1f8fab
fix test
tarrinneal Jan 17, 2025
96d129b
comments and test fixes
tarrinneal Jan 24, 2025
e89421c
rename setStringList methods
tarrinneal Jan 24, 2025
88ce597
Merge branch 'main' of github.com:flutter/packages into listString-en…
tarrinneal Jan 24, 2025
7e28547
fix kotlin tests and format
tarrinneal Jan 24, 2025
1cdce8d
fix java tests too
tarrinneal Jan 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rest of the comments
  • Loading branch information
tarrinneal committed Jan 6, 2025
commit 2c10fb7ba68faf30874e05a971ad45a9d32bbd76
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
public class LegacySharedPreferencesPlugin implements FlutterPlugin, SharedPreferencesApi {
private static final String TAG = "SharedPreferencesPlugin";
private static final String SHARED_PREFERENCES_NAME = "FlutterSharedPreferences";
// All identifiers must match the SharedPreferencesPlugin.kt file, as well as the strings.dart file.
private static final String JSON_LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu!";
private static final String LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu";
private static final String BIG_INTEGER_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy";
Expand Down Expand Up @@ -102,6 +103,7 @@ public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding bin
}

// Deprecated, for testing purposes only.
@Deprecated
@Override
public @NonNull Boolean setStringList(@NonNull String key, @NonNull List<String> value)
throws RuntimeException {
Expand Down Expand Up @@ -150,10 +152,14 @@ public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding bin
private Object transformPref(@NonNull String key, @NonNull Object value) {
if (value instanceof String) {
String stringValue = (String) value;
if (stringValue.startsWith(JSON_LIST_IDENTIFIER)) {
return value;
} else if (stringValue.startsWith(LIST_IDENTIFIER)) {
return listEncoder.decode(stringValue.substring(LIST_IDENTIFIER.length()));

if (value.startsWith(LIST_PREFIX)) {
// The newer JSON-encoded lists use an extended prefix to distinguish them.
if (value.startsWith(JSON_LIST_PREFIX)) {
return value;
} else {
return listEncoder.decode(stringValue.substring(LIST_IDENTIFIER.length()));
}
} else if (stringValue.startsWith(BIG_INTEGER_PREFIX)) {
// TODO (tarrinneal): Remove all BigInt code.
// https://github.com/flutter/flutter/issues/124420
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,16 @@ public interface SharedPreferencesApi {
/** Adds property to shared preferences data set of type double. */
@NonNull
Boolean setDouble(@NonNull String key, @NonNull Double value);
/** Adds property to shared preferences data set of type List<String>. */
@NonNull
Boolean setStringList(@NonNull String key, @NonNull String value);
/**
* Adds property to shared preferences data set of type List<String>.
*
* <p>Deprecated, this is only here for testing purposes.
*/
@NonNull
Boolean setStringList(@NonNull String key, @NonNull List<String> value);
Boolean setDeprecatedStringList(@NonNull String key, @NonNull List<String> value);
/** Removes all properties from shared preferences data set with matching prefix. */
@NonNull
Boolean clear(@NonNull String prefix, @Nullable List<String> allowList);
Expand Down Expand Up @@ -280,7 +283,7 @@ static void setUp(
ArrayList<Object> wrapped = new ArrayList<>();
ArrayList<Object> args = (ArrayList<Object>) message;
String keyArg = (String) args.get(0);
List<String> valueArg = (List<String>) args.get(1);
String valueArg = (String) args.get(1);
try {
Boolean output = api.setStringList(keyArg, valueArg);
wrapped.add(0, output);
Expand All @@ -293,6 +296,34 @@ static void setUp(
channel.setMessageHandler(null);
}
}
{
BinaryMessenger.TaskQueue taskQueue = binaryMessenger.makeBackgroundTaskQueue();
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setDeprecatedStringList"
+ messageChannelSuffix,
getCodec(),
taskQueue);
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<>();
ArrayList<Object> args = (ArrayList<Object>) message;
String keyArg = (String) args.get(0);
List<String> valueArg = (List<String>) args.get(1);
try {
Boolean output = api.setDeprecatedStringList(keyArg, valueArg);
wrapped.add(0, output);
} catch (Throwable exception) {
wrapped = wrapError(exception);
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BinaryMessenger.TaskQueue taskQueue = binaryMessenger.makeBackgroundTaskQueue();
BasicMessageChannel<Object> channel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,18 @@ interface SharedPreferencesAsyncApi {
fun setInt(key: String, value: Long, options: SharedPreferencesPigeonOptions)
/** Adds property to shared preferences data set of type double. */
fun setDouble(key: String, value: Double, options: SharedPreferencesPigeonOptions)
/** Adds property to shared preferences data set of type List<String>. */
fun setStringList(key: String, value: String, options: SharedPreferencesPigeonOptions)
/**
* Adds property to shared preferences data set of type List<String>.
*
* Deprecated, this is only here for testing purposes.
*/
fun setStringList(key: String, value: List<String>, options: SharedPreferencesPigeonOptions)
fun setDeprecatedStringList(
key: String,
value: List<String>,
options: SharedPreferencesPigeonOptions
)
/** Gets individual String value stored with [key], if any. */
fun getString(key: String, options: SharedPreferencesPigeonOptions): String?
/** Gets individual void value stored with [key], if any. */
Expand Down Expand Up @@ -252,7 +258,7 @@ interface SharedPreferencesAsyncApi {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val keyArg = args[0] as String
val valueArg = args[1] as List<String>
val valueArg = args[1] as String
val optionsArg = args[2] as SharedPreferencesPigeonOptions
val wrapped: List<Any?> =
try {
Expand All @@ -267,6 +273,33 @@ interface SharedPreferencesAsyncApi {
channel.setMessageHandler(null)
}
}
run {
val taskQueue = binaryMessenger.makeBackgroundTaskQueue()
val channel =
BasicMessageChannel<Any?>(
binaryMessenger,
"dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDeprecatedStringList$separatedMessageChannelSuffix",
codec,
taskQueue)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val keyArg = args[0] as String
val valueArg = args[1] as List<String>
val optionsArg = args[2] as SharedPreferencesPigeonOptions
val wrapped: List<Any?> =
try {
api.setDeprecatedStringList(keyArg, valueArg, optionsArg)
listOf(null)
} catch (exception: Throwable) {
wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run {
val taskQueue = binaryMessenger.makeBackgroundTaskQueue()
val channel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import kotlinx.coroutines.runBlocking

const val TAG = "SharedPreferencesPlugin"
const val SHARED_PREFERENCES_NAME = "FlutterSharedPreferences"
// All identifiers must match the LegacySharedPreferencesPlugin.java file, as well as the
// strings.dart file.
const val LIST_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu"
const val JSON_LIST_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu!"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be the same value as LegacySharedPreferencesPlugin? If so can you add comment as to why and that they need to be identical?

Same comments as above about using similar strings. I think this should be a different value entirely.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The legacy system and the new system can both read from the same files, so we need the same prefixes

const val DOUBLE_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu"
Expand Down Expand Up @@ -411,10 +413,13 @@ internal fun preferencesFilter(key: String, value: Any?, allowList: Set<String>?
/** Transforms preferences that are stored as Strings back to original type. */
internal fun transformPref(value: Any?, listEncoder: SharedPreferencesListEncoder): Any? {
if (value is String) {
if (value.startsWith(JSON_LIST_PREFIX)) {
return value
} else if (value.startsWith(LIST_PREFIX)) {
return listEncoder.decode(value.substring(LIST_PREFIX.length))
if (value.startsWith(LIST_PREFIX)) {
// The newer JSON-encoded lists use an extended prefix to distinguish them.
if (value.startsWith(JSON_LIST_PREFIX)) {
return value
} else {
return listEncoder.decode(value.substring(LIST_PREFIX.length))
}
} else if (value.startsWith(DOUBLE_PREFIX)) {
return value.substring(DOUBLE_PREFIX.length).toDouble()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,10 +799,10 @@ void main() {
await clearPreferences(preferences, options);
await preferences.setStringListLegacyForTesting(
listKey, testList, options);
final List<String>? oldSystemList =
final List<String>? platformEncodedList =
await preferences.getStringList(listKey, options);
expect(oldSystemList, testList);
await preferences.setStringList(listKey, oldSystemList!, options);
expect(platformEncodedList, testList);
await preferences.setStringList(listKey, platformEncodedList!, options);
expect(await preferences.getStringList(listKey, options), testList);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,42 @@ class SharedPreferencesApi {
}
}

/// Adds property to shared preferences data set of type List<String>.
Future<bool> setStringList(String key, String value) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setStringList$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_channel.send(<Object?>[key, value]) as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as bool?)!;
}
}

/// Adds property to shared preferences data set of type List<String>.
///
/// Deprecated, this is only here for testing purposes.
Future<bool> setStringList(String key, List<String> value) async {
Future<bool> setDeprecatedStringList(String key, List<String> value) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setStringList$pigeonVar_messageChannelSuffix';
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesApi.setDeprecatedStringList$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,39 @@ class SharedPreferencesAsyncApi {
}
}

/// Adds property to shared preferences data set of type List<String>.
Future<void> setStringList(
String key, String value, SharedPreferencesPigeonOptions options) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final List<Object?>? pigeonVar_replyList = await pigeonVar_channel
.send(<Object?>[key, value, options]) as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}

/// Adds property to shared preferences data set of type List<String>.
///
/// Deprecated, this is only here for testing purposes.
Future<void> setStringList(String key, List<String> value,
Future<void> setDeprecatedStringList(String key, List<String> value,
SharedPreferencesPigeonOptions options) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList$pigeonVar_messageChannelSuffix';
'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDeprecatedStringList$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ class SharedPreferencesAndroid extends SharedPreferencesStorePlatform {
case 'Double':
return _api.setDouble(key, value as double);
case 'StringList':
return _api.setString(key, '$jsonListPrefix${jsonEncode(value)}');
return _api.setStringList(key, '$jsonListPrefix${jsonEncode(value)}');
case 'PlatformEncodedStringListForTesting':
return _api.setStringList(key, value as List<String>);
return _api.setDeprecatedStringList(key, value as List<String>);
}
// TODO(tarrinneal): change to ArgumentError across all platforms.
throw PlatformException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ base class SharedPreferencesAsyncAndroid
return api.setString(key, stringValue, pigeonOptions);
}

/// Adds a `List<String>` to preferences using the no longer used system to test
/// moving from the old system to the new one.
/// Adds a `List<String>` to preferences using platform encoding to test
/// moving from platform encoding to json encoding.
@visibleForTesting
Future<void> setStringListLegacyForTesting(
String key,
Expand All @@ -148,7 +148,7 @@ base class SharedPreferencesAsyncAndroid
final SharedPreferencesPigeonOptions pigeonOptions =
_convertOptionsToPigeonOptions(options);
final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions);
return api.setStringList(key, value, pigeonOptions);
return api.setDeprecatedStringList(key, value, pigeonOptions);
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ abstract class SharedPreferencesApi {
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
bool setDouble(String key, double value);

/// Adds property to shared preferences data set of type List<String>.
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
bool setStringList(String key, String value);

/// Adds property to shared preferences data set of type List<String>.
///
/// Deprecated, this is only here for testing purposes.
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
bool setStringList(String key, List<String> value);
bool setDeprecatedStringList(String key, List<String> value);

/// Removes all properties from shared preferences data set with matching prefix.
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,19 @@ abstract class SharedPreferencesAsyncApi {
SharedPreferencesPigeonOptions options,
);

/// Adds property to shared preferences data set of type List<String>.
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
void setStringList(
String key,
String value,
SharedPreferencesPigeonOptions options,
);

/// Adds property to shared preferences data set of type List<String>.
///
/// Deprecated, this is only here for testing purposes.
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
void setStringList(
void setDeprecatedStringList(
String key,
List<String> value,
SharedPreferencesPigeonOptions options,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,17 @@ class _FakeSharedPreferencesApi implements SharedPreferencesApi {
}

@override
Future<bool> setStringList(String key, List<String?> value) async {
Future<bool> setStringList(String key, String value) async {
items[key] = '$jsonListPrefix${jsonEncode(value)}';
return true;
}

@override
Future<bool> setDeprecatedStringList(String key, List<String> value) async {
items[key] = value;
return true;
}

@override
// ignore: non_constant_identifier_names
BinaryMessenger? get pigeonVar_binaryMessenger => throw UnimplementedError();
Expand Down
Loading
Loading