1 /*
2 * Copyright (c) 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 "bundle_user_info.h"
17
18 #include <cerrno>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 #include "json_util.h"
24 #include "nlohmann/json.hpp"
25 #include "parcel_macro.h"
26 #include "string_ex.h"
27
28 namespace OHOS {
29 namespace AppExecFwk {
30 namespace {
31 const char* BUNDLE_USER_INFO_USER_ID = "userId";
32 const char* BUNDLE_USER_INFO_ENABLE = "enabled";
33 const char* BUNDLE_USER_INFO_DISABLE_ABILITIES = "disabledAbilities";
34 const char* BUNDLE_USER_INFO_OVERLAY_STATE = "overlayState";
35 const char* BUNDLE_USER_INFO_SET_ENABLED_CALLER = "setEnabledCaller";
36 } // namespace
37
ReadFromParcel(Parcel & parcel)38 bool BundleUserInfo::ReadFromParcel(Parcel &parcel)
39 {
40 userId = parcel.ReadInt32();
41 enabled = parcel.ReadBool();
42 int32_t disabledAbilitiesSize;
43 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, disabledAbilitiesSize);
44 CONTAINER_SECURITY_VERIFY(parcel, disabledAbilitiesSize, &disabledAbilities);
45 for (int32_t i = 0; i < disabledAbilitiesSize; i++) {
46 disabledAbilities.emplace_back(Str16ToStr8(parcel.ReadString16()));
47 }
48
49 int32_t overlayStateSize;
50 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, overlayStateSize);
51 CONTAINER_SECURITY_VERIFY(parcel, overlayStateSize, &overlayModulesState);
52 for (int32_t i = 0; i < overlayStateSize; i++) {
53 overlayModulesState.emplace_back(Str16ToStr8(parcel.ReadString16()));
54 }
55 setEnabledCaller = Str16ToStr8(parcel.ReadString16());
56 return true;
57 }
58
Unmarshalling(Parcel & parcel)59 BundleUserInfo *BundleUserInfo::Unmarshalling(Parcel &parcel)
60 {
61 BundleUserInfo *info = new (std::nothrow) BundleUserInfo();
62 if (info && !info->ReadFromParcel(parcel)) {
63 APP_LOGW("read from parcel failed");
64 delete info;
65 info = nullptr;
66 }
67
68 return info;
69 }
70
Marshalling(Parcel & parcel) const71 bool BundleUserInfo::Marshalling(Parcel &parcel) const
72 {
73 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, userId);
74 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, enabled);
75 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, disabledAbilities.size());
76 for (auto &disabledAbility : disabledAbilities) {
77 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(disabledAbility));
78 }
79 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, overlayModulesState.size());
80 for (const auto &overlayModuleState : overlayModulesState) {
81 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(overlayModuleState));
82 }
83 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(setEnabledCaller));
84 return true;
85 }
86
Dump(const std::string & prefix,int fd)87 void BundleUserInfo::Dump(const std::string &prefix, int fd)
88 {
89 APP_LOGI("called dump BundleUserInfo");
90 if (fd < 0) {
91 APP_LOGE("dump BundleUserInfo fd error");
92 return;
93 }
94 int flags = fcntl(fd, F_GETFL);
95 if (flags < 0) {
96 APP_LOGE("BundleUserInfo fcntl error %{public}s", strerror(errno));
97 return;
98 }
99 uint uflags = static_cast<uint>(flags);
100 uflags &= O_ACCMODE;
101 if ((uflags == O_WRONLY) || (uflags == O_RDWR)) {
102 nlohmann::json jsonObject = *this;
103 std::string result;
104 result.append(prefix);
105 result.append(jsonObject.dump(Constants::DUMP_INDENT));
106 int ret = TEMP_FAILURE_RETRY(write(fd, result.c_str(), result.size()));
107 if (ret < 0) {
108 APP_LOGE("BundleUserInfo write error %{public}s", strerror(errno));
109 }
110 }
111 }
112
IsInitialState() const113 bool BundleUserInfo::IsInitialState() const
114 {
115 return enabled && disabledAbilities.empty();
116 }
117
Reset()118 void BundleUserInfo::Reset()
119 {
120 enabled = true;
121 disabledAbilities.clear();
122 }
123
to_json(nlohmann::json & jsonObject,const BundleUserInfo & bundleUserInfo)124 void to_json(nlohmann::json& jsonObject, const BundleUserInfo& bundleUserInfo)
125 {
126 jsonObject = nlohmann::json {
127 {BUNDLE_USER_INFO_USER_ID, bundleUserInfo.userId},
128 {BUNDLE_USER_INFO_ENABLE, bundleUserInfo.enabled},
129 {BUNDLE_USER_INFO_DISABLE_ABILITIES, bundleUserInfo.disabledAbilities},
130 {BUNDLE_USER_INFO_OVERLAY_STATE, bundleUserInfo.overlayModulesState},
131 {BUNDLE_USER_INFO_SET_ENABLED_CALLER, bundleUserInfo.setEnabledCaller},
132 };
133 }
134
from_json(const nlohmann::json & jsonObject,BundleUserInfo & bundleUserInfo)135 void from_json(const nlohmann::json& jsonObject, BundleUserInfo& bundleUserInfo)
136 {
137 const auto &jsonObjectEnd = jsonObject.end();
138 int32_t parseResult = ERR_OK;
139 GetValueIfFindKey<int32_t>(jsonObject,
140 jsonObjectEnd,
141 BUNDLE_USER_INFO_USER_ID,
142 bundleUserInfo.userId,
143 JsonType::NUMBER,
144 false,
145 parseResult,
146 ArrayType::NOT_ARRAY);
147 GetValueIfFindKey<bool>(jsonObject,
148 jsonObjectEnd,
149 BUNDLE_USER_INFO_ENABLE,
150 bundleUserInfo.enabled,
151 JsonType::BOOLEAN,
152 false,
153 parseResult,
154 ArrayType::NOT_ARRAY);
155 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
156 jsonObjectEnd,
157 BUNDLE_USER_INFO_DISABLE_ABILITIES,
158 bundleUserInfo.disabledAbilities,
159 JsonType::ARRAY,
160 false,
161 parseResult,
162 ArrayType::STRING);
163 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
164 jsonObjectEnd,
165 BUNDLE_USER_INFO_OVERLAY_STATE,
166 bundleUserInfo.overlayModulesState,
167 JsonType::ARRAY,
168 false,
169 parseResult,
170 ArrayType::STRING);
171 GetValueIfFindKey<std::string>(jsonObject,
172 jsonObjectEnd,
173 BUNDLE_USER_INFO_SET_ENABLED_CALLER,
174 bundleUserInfo.setEnabledCaller,
175 JsonType::STRING,
176 false,
177 parseResult,
178 ArrayType::NOT_ARRAY);
179 if (parseResult != ERR_OK) {
180 APP_LOGE("module bundleUserInfo jsonObject error : %{public}d", parseResult);
181 }
182 }
183 } // namespace AppExecFwk
184 } // namespace OHOS