android_native_keyring_store/
shared_preferences.rs1use crate::methods::{ClassDecl, FromValue, JResult, Method, NoParam, SignatureComp};
2use base64::{Engine, prelude::BASE64_STANDARD};
3use jni::{
4 JNIEnv,
5 objects::{GlobalRef, JObject},
6};
7use std::marker::PhantomData;
8
9pub struct Context {
10 self_: GlobalRef,
11}
12impl Context {
13 pub fn new(env: &JNIEnv, obj: JObject) -> JResult<Self> {
14 Ok(Self {
15 self_: env.new_global_ref(obj)?,
16 })
17 }
18
19 pub fn get_shared_preferences(
20 &self,
21 env: &mut JNIEnv,
22 name: &str,
23 mode: i32,
24 ) -> JResult<SharedPreferences> {
25 struct ThisMethod<'a>(PhantomData<&'a ()>);
26 impl<'a> Method for ThisMethod<'a> {
27 type Param = (&'a str, i32);
28 type Return = SharedPreferences;
29
30 const NAME: &'static str = "getSharedPreferences";
31 }
32
33 ThisMethod::call(&self.self_, env, (name, mode))
34 }
35
36 pub fn id(&self) -> usize {
37 self.self_.as_raw() as usize
38 }
39}
40
41pub struct SharedPreferences {
42 self_: GlobalRef,
43}
44impl FromValue for SharedPreferences {
45 fn signature() -> SignatureComp {
46 Self::class().into()
47 }
48
49 fn from_object(self_: GlobalRef, _env: &mut JNIEnv) -> JResult<Self> {
50 Ok(Self { self_ })
51 }
52}
53impl SharedPreferences {
54 fn class() -> ClassDecl {
55 ClassDecl("Landroid/content/SharedPreferences;")
56 }
57
58 pub fn get_string(&self, env: &mut JNIEnv, key: &str) -> JResult<Option<String>> {
59 struct ThisMethod<'a>(PhantomData<&'a ()>);
60 impl<'a> Method for ThisMethod<'a> {
61 type Param = (&'a str, Option<&'a str>);
62 type Return = Option<String>;
63
64 const NAME: &'static str = "getString";
65 }
66 ThisMethod::call(&self.self_, env, (key, None))
67 }
68
69 pub fn get_binary(&self, env: &mut JNIEnv, key: &str) -> JResult<Option<Vec<u8>>> {
70 let Some(b64) = self.get_string(env, key)? else {
71 return Ok(None);
72 };
73
74 Ok(match BASE64_STANDARD.decode(&b64) {
75 Ok(data) => Some(data),
76 Err(e) => {
77 tracing::error!(%e, "Error decoding base64 data, ignoring value");
78 tracing::debug!(?e, ?b64);
79 None
80 }
81 })
82 }
83
84 pub fn edit(&self, env: &mut JNIEnv) -> JResult<SharedPreferencesEditor> {
85 struct ThisMethod;
86 impl Method for ThisMethod {
87 type Param = NoParam;
88 type Return = SharedPreferencesEditor;
89
90 const NAME: &str = "edit";
91 }
92 ThisMethod::call(&self.self_, env, NoParam)
93 }
94}
95
96pub struct SharedPreferencesEditor {
97 self_: GlobalRef,
98}
99impl FromValue for SharedPreferencesEditor {
100 fn signature() -> SignatureComp {
101 Self::class().into()
102 }
103
104 fn from_object(self_: GlobalRef, _env: &mut JNIEnv) -> JResult<Self> {
105 Ok(Self { self_ })
106 }
107}
108impl SharedPreferencesEditor {
109 fn class() -> ClassDecl {
110 ClassDecl("Landroid/content/SharedPreferences$Editor;")
111 }
112
113 pub fn put_string(&self, env: &mut JNIEnv, key: &str, value: &str) -> JResult<Self> {
114 struct ThisMethod<'a>(PhantomData<&'a ()>);
115 impl<'a> Method for ThisMethod<'a> {
116 type Param = (&'a str, &'a str);
117 type Return = SharedPreferencesEditor;
118
119 const NAME: &'static str = "putString";
120 }
121 ThisMethod::call(&self.self_, env, (key, value))
122 }
123
124 pub fn put_binary(&self, env: &mut JNIEnv, key: &str, value: &[u8]) -> JResult<Self> {
125 let value = BASE64_STANDARD.encode(value);
126 self.put_string(env, key, &value)
127 }
128
129 pub fn remove(&self, env: &mut JNIEnv, key: &str) -> JResult<Self> {
130 struct ThisMethod<'a>(PhantomData<&'a ()>);
131 impl<'a> Method for ThisMethod<'a> {
132 type Param = &'a str;
133 type Return = SharedPreferencesEditor;
134
135 const NAME: &'static str = "remove";
136 }
137 ThisMethod::call(&self.self_, env, key)
138 }
139
140 pub fn commit(&self, env: &mut JNIEnv) -> JResult<bool> {
141 struct ThisMethod;
142 impl Method for ThisMethod {
143 type Param = NoParam;
144 type Return = bool;
145
146 const NAME: &str = "commit";
147 }
148 ThisMethod::call(&self.self_, env, NoParam)
149 }
150}