1 /*
2 * Copyright (c) 2021-2022 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 "bridge/declarative_frontend/jsview/js_persistent.h"
17
18 #include "base/memory/referenced.h"
19 #include "core/common/ace_engine.h"
20 #include "core/common/container.h"
21 #include "core/common/storage/storage_proxy.h"
22 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
23
24 namespace OHOS::Ace::Framework {
25 constexpr int32_t DATA_REQUIRED_ARGS = 2;
26
JSBind(BindingTarget globalObj)27 void JSPersistent::JSBind(BindingTarget globalObj)
28 {
29 JSClass<JSPersistent>::Declare("Storage");
30 JSClass<JSPersistent>::CustomMethod("set", &JSPersistent::Set);
31 JSClass<JSPersistent>::CustomMethod("get", &JSPersistent::Get);
32 JSClass<JSPersistent>::CustomMethod("has", &JSPersistent::Has);
33 JSClass<JSPersistent>::CustomMethod("clear", &JSPersistent::Clear);
34 JSClass<JSPersistent>::CustomMethod("delete", &JSPersistent::Delete);
35 JSClass<JSPersistent>::Bind(globalObj, JSPersistent::ConstructorCallback, JSPersistent::DestructorCallback);
36 }
37
ConstructorCallback(const JSCallbackInfo& args)38 void JSPersistent::ConstructorCallback(const JSCallbackInfo& args)
39 {
40 bool needCrossThread = false;
41 if (args.Length() > 0 && args[0]->IsBoolean()) {
42 needCrossThread = args[0]->ToBoolean();
43 }
44 std::string fileName;
45 auto persistent = Referenced::MakeRefPtr<JSPersistent>(needCrossThread, fileName);
46 persistent->IncRefCount();
47 args.SetReturnValue(Referenced::RawPtr(persistent));
48 }
49
DestructorCallback(JSPersistent* persistent)50 void JSPersistent::DestructorCallback(JSPersistent* persistent)
51 {
52 if (persistent != nullptr) {
53 persistent->DecRefCount();
54 }
55 }
56
Set(const JSCallbackInfo& args)57 void JSPersistent::Set(const JSCallbackInfo& args)
58 {
59 #if defined(PREVIEW)
60 LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
61 "emulator or a real device instead.");
62 return;
63 #endif
64 if (args.Length() < DATA_REQUIRED_ARGS || !args[0]->IsString()) {
65 LOGW("JSPersistent: Fail to set persistent data, args too few or key type is not a string");
66 return;
67 }
68 std::string key = args[0]->ToString();
69 auto serializedValue = JSON::Stringify(args.GetVm(), args[1].Get().GetLocalHandle());
70 std::string value = serializedValue->ToString(args.GetVm())->ToString(args.GetVm());
71 if (!StorageProxy::GetInstance()->GetStorage()) {
72 LOGW("no storage available");
73 return;
74 }
75 StorageProxy::GetInstance()->GetStorage()->SetString(key, value);
76 }
77
Get(const JSCallbackInfo& args)78 void JSPersistent::Get(const JSCallbackInfo& args)
79 {
80 #if defined(PREVIEW)
81 LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
82 "emulator or a real device instead.");
83 return;
84 #endif
85 if (args.Length() < 1 || !args[0]->IsString()) {
86 return;
87 }
88 auto storage = StorageProxy::GetInstance()->GetStorage();
89 if (!storage) {
90 LOGW("no storage available");
91 return;
92 }
93 std::string key = args[0]->ToString();
94 std::string value = storage->GetString(key);
95 if (value.empty() || value == "undefined") {
96 args.SetReturnValue(JSVal::Undefined());
97 return;
98 }
99 JSRef<JSObject> obj = JSRef<JSObject>::New();
100 JSRef<JSVal> ret = obj->ToJsonObject(value.c_str());
101 args.SetReturnValue(ret);
102 }
103
Has(const JSCallbackInfo& args)104 void JSPersistent::Has(const JSCallbackInfo& args)
105 {
106 #if defined(PREVIEW)
107 LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
108 "emulator or a real device instead.");
109 return;
110 #endif
111 if (args.Length() < 1 || !args[0]->IsString()) {
112 LOGW("JSPersistent: Failed to Get persistent data, args too few");
113 return;
114 }
115 std::string key = args[0]->ToString();
116 if (!StorageProxy::GetInstance()->GetStorage()) {
117 LOGW("no storage available");
118 return;
119 }
120 std::string value = StorageProxy::GetInstance()->GetStorage()->GetString(key);
121 args.SetReturnValue(value.empty()? JSVal::False() : JSVal::True());
122 }
123
Delete(const JSCallbackInfo& args)124 void JSPersistent::Delete(const JSCallbackInfo& args)
125 {
126 #if defined(PREVIEW)
127 LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
128 "emulator or a real device instead.");
129 return;
130 #endif
131 if (args.Length() < 1 || !args[0]->IsString()) {
132 return;
133 }
134 std::string key = args[0]->ToString();
135 if (!StorageProxy::GetInstance()->GetStorage()) {
136 LOGW("no storage available");
137 return;
138 }
139 StorageProxy::GetInstance()->GetStorage()->Delete(key);
140 }
141
Clear(const JSCallbackInfo& args)142 void JSPersistent::Clear(const JSCallbackInfo& args)
143 {
144 #if defined(PREVIEW)
145 LOGW("[Engine Log] Unable to use the PersistentStorage in the Previewer. Perform this operation on the "
146 "emulator or a real device instead.");
147 return;
148 #endif
149 if (!StorageProxy::GetInstance()->GetStorage()) {
150 LOGW("no storage available");
151 return;
152 }
153 StorageProxy::GetInstance()->GetStorage()->Clear();
154 }
155
156 } // namespace OHOS::Ace::Framework