also looking at this
refactor(android): one SharedPreferences helper, after the third caller turned out to be dead
#170
Merged
chris
wants to merge
refactor/android-prefs
into
main
3 files
+165
-113
| @@ -25,6 +25,7 @@ | ||
| 25 | 25 | const std = ; |
| 26 | 26 | const jni = ; |
| 27 | 27 | const bridge_error = ; |
| 28 | +const prefs_api = ; | |
| 28 | 29 | |
| 29 | 30 | const Jni = jni.Jni; |
| 30 | 31 | const jobject = jni.jobject; |
| @@ -38,9 +39,6 @@ pub const A = struct { | ||
| 38 | 39 | pub const resolve_global = "_craftSharedKeychainResolve"; |
| 39 | 40 | pub const reject_global = "_craftSharedKeychainReject"; |
| 40 | 41 | |
| 41 | -/// `Context.MODE_PRIVATE`, a compile-time constant the shim's DEX holds as 0. | |
| 42 | -const mode_private: i32 = 0; | |
| 43 | - | |
| 44 | 42 | const prefix = "craft_shared"; |
| 45 | 43 | |
| 46 | 44 | /// `if (group.isNotEmpty()) "craft_shared_$group" else "craft_shared"`. |
| @@ -97,17 +95,7 @@ pub fn valuePayload(allocator: std.mem.Allocator, key: []const u8, value: ?[]con | ||
| 97 | 95 | fn openPrefs(j: Jni, allocator: std.mem.Allocator, activity: jobject, group: []const u8) !jobject { |
| 98 | 96 | const name = try prefsName(allocator, group); |
| 99 | 97 | defer allocator.free(name); |
| 100 | - | |
| 101 | - const activity_cls = try j.objectClass(activity); | |
| 102 | - return j.callObjectMethodA( | |
| 103 | - activity, | |
| 104 | - try j.methodId( | |
| 105 | - activity_cls, | |
| 106 | - "getSharedPreferences", | |
| 107 | - "(Ljava/lang/String;I)Landroid/content/SharedPreferences;", | |
| 108 | - ), | |
| 109 | - &.{ .{ .l = try j.newStringUtf8(allocator, name) }, .{ .i = mode_private } }, | |
| 110 | - ); | |
| 98 | + return prefs_api.open(j, allocator, activity, name); | |
| 111 | 99 | } |
| 112 | 100 | |
| 113 | 101 | /// `prefs.edit().putString(key, value).apply()`. |
| @@ -122,27 +110,9 @@ pub fn set( | ||
| 122 | 110 | try j.pushLocalFrame(16); |
| 123 | 111 | defer _ = j.popLocalFrame(null); |
| 124 | 112 | |
| 125 | - const prefs = try openPrefs(j, allocator, activity, group); | |
| 126 | - const editor = try editorFor(j, prefs); | |
| 127 | - const editor_cls = try j.objectClass(editor); | |
| 128 | - | |
| 129 | - _ = try j.callObjectMethodA( | |
| 130 | - editor, | |
| 131 | - try j.methodId( | |
| 132 | - editor_cls, | |
| 133 | - "putString", | |
| 134 | - "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;", | |
| 135 | - ), | |
| 136 | - &.{ | |
| 137 | - .{ .l = try j.newStringUtf8(allocator, key) }, | |
| 138 | - .{ .l = try j.newStringUtf8(allocator, value) }, | |
| 139 | - }, | |
| 140 | - ); | |
| 141 | - | |
| 142 | - // `apply` rather than `commit`: it writes on a background thread and | |
| 143 | - // returns void, so a failure is not observable here — which is exactly | |
| 144 | - // what the shim's resolve already promises regardless. | |
| 145 | - try j.callVoidMethodA(editor, try j.methodId(editor_cls, "apply", "()V"), &.{}); | |
| 113 | + const editor = try prefs_api.edit(j, try openPrefs(j, allocator, activity, group)); | |
| 114 | + try prefs_api.putString(j, allocator, editor, key, value); | |
| 115 | + try prefs_api.apply(j, editor); | |
| 146 | 116 | } |
| 147 | 117 | |
| 148 | 118 | /// `prefs.edit().remove(key).apply()`. |
| @@ -156,20 +126,9 @@ pub fn remove( | ||
| 156 | 126 | try j.pushLocalFrame(16); |
| 157 | 127 | defer _ = j.popLocalFrame(null); |
| 158 | 128 | |
| 159 | - const prefs = try openPrefs(j, allocator, activity, group); | |
| 160 | - const editor = try editorFor(j, prefs); | |
| 161 | - const editor_cls = try j.objectClass(editor); | |
| 162 | - | |
| 163 | - _ = try j.callObjectMethodA( | |
| 164 | - editor, | |
| 165 | - try j.methodId( | |
| 166 | - editor_cls, | |
| 167 | - "remove", | |
| 168 | - "(Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;", | |
| 169 | - ), | |
| 170 | - &.{.{ .l = try j.newStringUtf8(allocator, key) }}, | |
| 171 | - ); | |
| 172 | - try j.callVoidMethodA(editor, try j.methodId(editor_cls, "apply", "()V"), &.{}); | |
| 129 | + const editor = try prefs_api.edit(j, try openPrefs(j, allocator, activity, group)); | |
| 130 | + try prefs_api.remove(j, allocator, editor, key); | |
| 131 | + try prefs_api.apply(j, editor); | |
| 173 | 132 | } |
| 174 | 133 | |
| 175 | 134 | /// `prefs.getString(key, null)`, null included. |
| @@ -187,29 +146,7 @@ pub fn get( | ||
| 187 | 146 | defer _ = j.popLocalFrame(null); |
| 188 | 147 | |
| 189 | 148 | const prefs = try openPrefs(j, allocator, activity, group); |
| 190 | - const value = try j.callObjectMethodA( | |
| 191 | - prefs, | |
| 192 | - try j.methodId( | |
| 193 | - try j.objectClass(prefs), | |
| 194 | - "getString", | |
| 195 | - "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", | |
| 196 | - ), | |
| 197 | - &.{ .{ .l = try j.newStringUtf8(allocator, key) }, .{ .l = null } }, | |
| 198 | - ); | |
| 199 | - | |
| 200 | - if (value == null) return null; | |
| 201 | - return try j.stringToUtf8(allocator, value); | |
| 202 | -} | |
| 203 | - | |
| 204 | -fn editorFor(j: Jni, prefs: jobject) !jobject { | |
| 205 | - return j.callObjectMethod( | |
| 206 | - prefs, | |
| 207 | - try j.methodId( | |
| 208 | - try j.objectClass(prefs), | |
| 209 | - "edit", | |
| 210 | - "()Landroid/content/SharedPreferences$Editor;", | |
| 211 | - ), | |
| 212 | - ); | |
| 149 | + return prefs_api.getString(j, allocator, prefs, key); | |
| 213 | 150 | } |
| 214 | 151 | |
| 215 | 152 | // ============================================================================= |
| @@ -287,11 +224,6 @@ test "a key or value carrying a quote survives as JSON" { | ||
| 287 | 224 | try testing.expect(parsed_success.value.object.get("success").?.bool); |
| 288 | 225 | } |
| 289 | 226 | |
| 290 | -test "MODE_PRIVATE is zero" { | |
| 291 | - // A compile-time constant in Java, so the shim's DEX holds the literal. | |
| 292 | - try testing.expectEqual(@as(i32, 0), mode_private); | |
| 293 | -} | |
| 294 | - | |
| 295 | 227 | test "the actions and globals match the shim exactly" { |
| 296 | 228 | try testing.expectEqualStrings("setSharedItem", A.set_shared_item); |
| 297 | 229 | try testing.expectEqualStrings("getSharedItem", A.get_shared_item); |