1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cj_persistent_storage_ffi.h"
17 #include "cj_lambda.h"
18 #include "core/common/container.h"
19 #include "core/common/ace_engine.h"
20 #include "core/common/storage/storage_proxy.h"
21 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
22 
23 using namespace OHOS::Ace;
24 using namespace OHOS::FFI;
25 using namespace OHOS::Ace::Framework;
26 
GetValueFromStorage(std::string key,std::string & result)27 bool GetValueFromStorage(std::string key, std::string& result)
28 {
29     auto container = Container::Current();
30     if (!container) {
31         return false;
32     }
33     auto executor = container->GetTaskExecutor();
34     std::string valueStr = StorageProxy::GetInstance()->GetStorage()->GetString(key);
35     if (valueStr.empty()) {
36         return false;
37     }
38     result = valueStr;
39     return true;
40 }
41 
SetValueToStorage(std::string key,std::string value)42 void SetValueToStorage(std::string key, std::string value)
43 {
44     auto container = Container::Current();
45     if (!container) {
46         return;
47     }
48     auto executor = container->GetTaskExecutor();
49     if (!StorageProxy::GetInstance()->GetStorage()) {
50         LOGW("no storage available");
51         return;
52     }
53     StorageProxy::GetInstance()->GetStorage()->SetString(key, value);
54 }
55 
56 extern "C" {
FfiOHOSAceFrameworkPersistentGetString(const char * key)57 NativeOptionCString FfiOHOSAceFrameworkPersistentGetString(const char* key)
58 {
59     NativeOptionCString result {.hasValue = false, .value = Utils::MallocCString("").value};
60 #if defined(PREVIEW)
61     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
62         "emulator or a real device instead.");
63     return result;
64 #endif
65     std::string tmp;
66     if (GetValueFromStorage(key, tmp)) {
67         result.hasValue = true;
68         result.value = Utils::MallocCString(tmp).value;
69     }
70     return result;
71 }
72 
FfiOHOSAceFrameworkPersistentSetString(const char * key,const char * value,NotifyCallbackString callback)73 void FfiOHOSAceFrameworkPersistentSetString(const char* key, const char* value, NotifyCallbackString callback)
74 {
75 #if defined(PREVIEW)
76     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
77     "emulator or a real device instead.");
78     return;
79 #endif
80     SetValueToStorage(key, value);
81     auto cjCallback = [func = CJLambda::Create(callback), key, value]() {
82         func(key, value);
83     };
84     cjCallback();
85 }
86 
FfiOHOSAceFrameworkPersistentGetInt64(const char * key)87 NativeOptionInt64 FfiOHOSAceFrameworkPersistentGetInt64(const char* key)
88 {
89     NativeOptionInt64 result {.hasValue = false, .value = 0};
90 #if defined(PREVIEW)
91     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
92         "emulator or a real device instead.");
93     return result;
94 #endif
95     std::string tmp;
96     if (GetValueFromStorage(key, tmp)) {
97         result.hasValue = true;
98         result.value = std::stoll(tmp);
99     }
100     return result;
101 }
102 
FfiOHOSAceFrameworkPersistentSetInt64(const char * key,int64_t value,NotifyCallbackInt64 callback)103 void FfiOHOSAceFrameworkPersistentSetInt64(const char* key, int64_t value, NotifyCallbackInt64 callback)
104 {
105 #if defined(PREVIEW)
106     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
107     "emulator or a real device instead.");
108     return;
109 #endif
110     std::string tmp = std::to_string(value);
111     SetValueToStorage(key, tmp);
112     auto cjCallback = [func = CJLambda::Create(callback), key, value]() {
113         func(key, value);
114     };
115     cjCallback();
116 }
117 
FfiOHOSAceFrameworkPersistentGetFloat64(const char * key)118 NativeOptionFloat64 FfiOHOSAceFrameworkPersistentGetFloat64(const char* key)
119 {
120     NativeOptionFloat64 result {.hasValue = false, .value = 0.0};
121 #if defined(PREVIEW)
122     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
123         "emulator or a real device instead.");
124     return result;
125 #endif
126     std::string tmp;
127     if (GetValueFromStorage(key, tmp)) {
128         result.hasValue = true;
129         result.value = std::stod(tmp);
130     }
131     return result;
132 }
133 
FfiOHOSAceFrameworkPersistentSetFloat64(const char * key,double value,NotifyCallbackFloat64 callback)134 void FfiOHOSAceFrameworkPersistentSetFloat64(const char* key, double value, NotifyCallbackFloat64 callback)
135 {
136 #if defined(PREVIEW)
137     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
138     "emulator or a real device instead.");
139     return;
140 #endif
141     std::string tmp = std::to_string(value);
142     SetValueToStorage(key, tmp);
143     auto cjCallback = [func = CJLambda::Create(callback), key, value]() {
144         func(key, value);
145     };
146     cjCallback();
147 }
148 
FfiOHOSAceFrameworkPersistentGetBool(const char * key)149 NativeOptionBool FfiOHOSAceFrameworkPersistentGetBool(const char* key)
150 {
151     NativeOptionBool result {.hasValue = false, .value = false};
152 #if defined(PREVIEW)
153     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
154         "emulator or a real device instead.");
155     return result;
156 #endif
157     std::string tmp;
158     if (GetValueFromStorage(key, tmp)) {
159         result.hasValue = true;
160         result.value = tmp == "true";
161     }
162     return result;
163 }
164 
FfiOHOSAceFrameworkPersistentSetBool(const char * key,bool value,NotifyCallbackBool callback)165 void FfiOHOSAceFrameworkPersistentSetBool(const char* key, bool value, NotifyCallbackBool callback)
166 {
167 #if defined(PREVIEW)
168     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
169     "emulator or a real device instead.");
170     return;
171 #endif
172     std::string tmp = value ? "true": "false";
173     SetValueToStorage(key, tmp);
174     auto cjCallback = [func = CJLambda::Create(callback), key, value]() {
175         func(key, value);
176     };
177     cjCallback();
178 }
179 
FfiOHOSAceFrameworkPersistentDelete(const char * key)180 void FfiOHOSAceFrameworkPersistentDelete(const char* key)
181 {
182 #if defined(PREVIEW)
183     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
184         "emulator or a real device instead.");
185     return;
186 #endif
187     auto container = Container::Current();
188     if (!container) {
189         return;
190     }
191     auto executor = container->GetTaskExecutor();
192     StorageProxy::GetInstance()->GetStorage()->Delete(key);
193 }
FfiOHOSAceFrameworkPersistentClear()194 void FfiOHOSAceFrameworkPersistentClear()
195 {
196 #if defined(PREVIEW)
197     LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
198         "emulator or a real device instead.");
199     return;
200 #endif
201     auto container = Container::Current();
202     if (!container) {
203         return;
204     }
205     auto executor = container->GetTaskExecutor();
206     StorageProxy::GetInstance()->GetStorage()->Clear();
207 }
208 }