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