1 /*
2 * Copyright (c) 2023 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 //! This module is used to Asset service hisysevent.
17
18 use std::cmp::min;
19 use std::time::Instant;
20
21 use hisysevent::{
22 build_array_params, build_number_param, build_str_param, build_string_array_params, write, EventType,
23 HiSysEventParam,
24 };
25 use ipc::Skeleton;
26
27 use asset_common::CallingInfo;
28 use asset_definition::{
29 Accessibility, AssetError, AssetMap, AuthType, Extension, OperationType, Result, ReturnType, SyncType, Tag,
30 };
31 use asset_log::{loge, logi};
32
33 /// Component name.
34 const COMPONENT: &str = "asset";
35 /// Partition name.
36 pub const PARTITION: &str = "/data";
37 /// Max asset file dir number.
38 const MAX_DIR_NUMBER: usize = 7;
39
40 /// System events structure which base on `Hisysevent`.
41 struct SysEvent<'a> {
42 event_type: EventType,
43 params: Vec<HiSysEventParam<'a>>,
44 domain: &'static str,
45 event_name: &'static str,
46 }
47
48 impl<'a> SysEvent<'a> {
49 const ASSET_DOMAIN: &str = "ASSET";
50 const FILEMANAGEMENT_DOMAIN: &str = "FILEMANAGEMENT";
51 const ASSET_FAULT: &str = "SECRET_STORE_OPERATION_FAILED";
52 const ASSET_STATISTIC: &str = "SECRET_STORE_INFO_COLLECTION";
53 const FILEMANAGEMENT_STATISTIC: &str = "USER_DATA_SIZE";
54
55 pub(crate) const FUNCTION: &str = "FUNCTION";
56 pub(crate) const USER_ID: &str = "USER_ID";
57 pub(crate) const CALLER: &str = "CALLER";
58 pub(crate) const ERROR_CODE: &str = "ERROR_CODE";
59 pub(crate) const RUN_TIME: &str = "RUN_TIME";
60 pub(crate) const EXTRA: &str = "EXTRA";
61 pub(crate) const COMPONENT_NAME: &str = "COMPONENT_NAME";
62 pub(crate) const PARTITION_NAME: &str = "PARTITION_NAME";
63 pub(crate) const REMAIN_PARTITION_SIZE: &str = "REMAIN_PARTITION_SIZE";
64 pub(crate) const FILE_OR_FOLDER_PATH: &str = "FILE_OR_FOLDER_PATH";
65 pub(crate) const FILE_OR_FOLDER_SIZE: &str = "FILE_OR_FOLDER_SIZE";
66
new(event_type: EventType, domain: &'static str, event_name: &'static str) -> Self67 fn new(event_type: EventType, domain: &'static str, event_name: &'static str) -> Self {
68 Self { event_type, domain, event_name, params: Vec::new() }
69 }
70
set_param(mut self, param: HiSysEventParam<'a>) -> Self71 fn set_param(mut self, param: HiSysEventParam<'a>) -> Self {
72 self.params.push(param);
73 self
74 }
75
write(self)76 fn write(self) {
77 write(self.domain, self.event_name, self.event_type, self.params.as_slice());
78 }
79 }
80
81 const EXTRA_ATTRS: [Tag; 7] = [
82 Tag::SyncType,
83 Tag::Accessibility,
84 Tag::RequirePasswordSet,
85 Tag::AuthType,
86 Tag::OperationType,
87 Tag::ReturnType,
88 Tag::RequireAttrEncrypted,
89 ];
90
transfer_tag_to_string(tags: &[Tag], attributes: &AssetMap) -> Result<String>91 fn transfer_tag_to_string(tags: &[Tag], attributes: &AssetMap) -> Result<String> {
92 let mut ext_info = "".to_string();
93 for tag in tags {
94 if attributes.get(tag).is_none() {
95 continue;
96 }
97 let tag_value = match tag {
98 Tag::SyncType => format!("{}", attributes.get_num_attr(tag).unwrap_or(SyncType::default() as u32)),
99 Tag::Accessibility => format!("{}", attributes.get_enum_attr(tag).unwrap_or(Accessibility::default())),
100 Tag::RequirePasswordSet => format!("{}", attributes.get_bool_attr(tag).unwrap_or(false)),
101 Tag::AuthType => format!("{}", attributes.get_enum_attr(tag).unwrap_or(AuthType::default())),
102 Tag::ReturnType => format!("{}", attributes.get_enum_attr(tag).unwrap_or(ReturnType::default())),
103 Tag::RequireAttrEncrypted => format!("{}", attributes.get_bool_attr(tag).unwrap_or(false)),
104 Tag::OperationType => {
105 format!("{}", attributes.get_num_attr(tag).unwrap_or(OperationType::default() as u32))
106 },
107 _ => String::new(),
108 };
109 ext_info += &format!("{}:{};", tag, tag_value);
110 }
111 Ok(ext_info)
112 }
113
construct_ext_info(attributes: &AssetMap) -> Result<String>114 fn construct_ext_info(attributes: &AssetMap) -> Result<String> {
115 let tags = EXTRA_ATTRS.to_vec();
116 transfer_tag_to_string(&tags, attributes)
117 }
118
upload_statistic_system_event( calling_info: &CallingInfo, start_time: Instant, func_name: &str, ext_info: &str, )119 pub(crate) fn upload_statistic_system_event(
120 calling_info: &CallingInfo,
121 start_time: Instant,
122 func_name: &str,
123 ext_info: &str,
124 ) {
125 let duration = start_time.elapsed();
126 let owner_info = String::from_utf8_lossy(calling_info.owner_info()).to_string();
127 SysEvent::new(EventType::Statistic, SysEvent::ASSET_DOMAIN, SysEvent::ASSET_STATISTIC)
128 .set_param(build_str_param!(SysEvent::FUNCTION, func_name))
129 .set_param(build_number_param!(SysEvent::USER_ID, calling_info.user_id()))
130 .set_param(build_str_param!(SysEvent::CALLER, owner_info.clone()))
131 .set_param(build_number_param!(SysEvent::RUN_TIME, duration.as_millis() as u32))
132 .set_param(build_str_param!(
133 SysEvent::EXTRA,
134 format!(
135 "CallingUid={} ext_info={} caller_owner_type={}",
136 Skeleton::calling_uid(),
137 ext_info,
138 calling_info.owner_type()
139 )
140 ))
141 .write();
142 logi!(
143 "[INFO]Calling fun:[{}], user_id:[{}], caller:[{}], start_time:[{:?}], run_time:[{}], ext_info=[{}]",
144 func_name,
145 calling_info.user_id(),
146 owner_info,
147 start_time,
148 duration.as_millis(),
149 ext_info
150 )
151 }
152
upload_fault_system_event( calling_info: &CallingInfo, start_time: Instant, func_name: &str, e: &AssetError, )153 pub(crate) fn upload_fault_system_event(
154 calling_info: &CallingInfo,
155 start_time: Instant,
156 func_name: &str,
157 e: &AssetError,
158 ) {
159 let owner_info = String::from_utf8_lossy(calling_info.owner_info()).to_string();
160 SysEvent::new(EventType::Fault, SysEvent::ASSET_DOMAIN, SysEvent::ASSET_FAULT)
161 .set_param(build_str_param!(SysEvent::FUNCTION, func_name))
162 .set_param(build_number_param!(SysEvent::USER_ID, calling_info.user_id()))
163 .set_param(build_str_param!(SysEvent::CALLER, owner_info.clone()))
164 .set_param(build_number_param!(SysEvent::ERROR_CODE, e.code as i32))
165 .set_param(build_str_param!(SysEvent::EXTRA, e.msg.clone()))
166 .write();
167 loge!(
168 "[ERROR]Calling fun:[{}], user_id:[{}], caller:[{}], start_time:[{:?}], error_code:[{}], error_msg:[{}]",
169 func_name,
170 calling_info.user_id(),
171 owner_info,
172 start_time,
173 e.code,
174 e.msg.clone()
175 );
176 }
177
upload_system_event<T>( result: Result<T>, calling_info: &CallingInfo, start_time: Instant, func_name: &str, attributes: &AssetMap, ) -> Result<T>178 pub(crate) fn upload_system_event<T>(
179 result: Result<T>,
180 calling_info: &CallingInfo,
181 start_time: Instant,
182 func_name: &str,
183 attributes: &AssetMap,
184 ) -> Result<T> {
185 let ext_info = construct_ext_info(attributes)?;
186 match &result {
187 Ok(_) => upload_statistic_system_event(calling_info, start_time, func_name, &ext_info),
188 Err(e) => upload_fault_system_event(calling_info, start_time, func_name, e),
189 }
190 result
191 }
192
193 /// upload data size
upload_data_size( remain_partition_size: f64, file_or_folder_path: Vec<String>, file_or_folder_size: Vec<u64>, )194 pub(crate) fn upload_data_size(
195 remain_partition_size: f64,
196 file_or_folder_path: Vec<String>,
197 file_or_folder_size: Vec<u64>,
198 ) {
199 let folder_path: Vec<&str> = file_or_folder_path.iter().map(|s| s.as_str()).collect();
200 let mut folder_size = [0u64; MAX_DIR_NUMBER];
201 let min_size = min(MAX_DIR_NUMBER, folder_path.len());
202 folder_size[..min_size].copy_from_slice(&file_or_folder_size[..min_size]);
203
204 SysEvent::new(EventType::Statistic, SysEvent::FILEMANAGEMENT_DOMAIN, SysEvent::FILEMANAGEMENT_STATISTIC)
205 .set_param(build_str_param!(SysEvent::COMPONENT_NAME, COMPONENT))
206 .set_param(build_str_param!(SysEvent::PARTITION_NAME, PARTITION))
207 .set_param(build_number_param!(SysEvent::REMAIN_PARTITION_SIZE, remain_partition_size))
208 .set_param(build_string_array_params!(SysEvent::FILE_OR_FOLDER_PATH, &folder_path))
209 .set_param(build_array_params!(SysEvent::FILE_OR_FOLDER_SIZE, &folder_size))
210 .write();
211 }
212