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::time::Instant;
19
20 use ipc::Skeleton;
21
22 use asset_common::CallingInfo;
23 use asset_definition::{
24 Accessibility, AssetError, AssetMap, AuthType, Extension, OperationType, Result, ReturnType, SyncType, Tag,
25 };
26 use asset_log::{loge, logi};
27
28 use hisysevent::{build_number_param, build_str_param, write, EventType, HiSysEventParam};
29
30 /// System events structure which base on `Hisysevent`.
31 struct SysEvent<'a> {
32 event_type: EventType,
33 params: Vec<HiSysEventParam<'a>>,
34 }
35
36 impl<'a> SysEvent<'a> {
37 const DOMAIN: &str = "ASSET";
38 const ASSET_FAULT: &str = "SECRET_STORE_OPERATION_FAILED";
39 const ASSET_STATISTIC: &str = "SECRET_STORE_INFO_COLLECTION";
40
41 pub(crate) const FUNCTION: &str = "FUNCTION";
42 pub(crate) const USER_ID: &str = "USER_ID";
43 pub(crate) const CALLER: &str = "CALLER";
44 pub(crate) const ERROR_CODE: &str = "ERROR_CODE";
45 pub(crate) const RUN_TIME: &str = "RUN_TIME";
46 pub(crate) const EXTRA: &str = "EXTRA";
47
new(event_type: EventType) -> Self48 fn new(event_type: EventType) -> Self {
49 Self { event_type, params: Vec::new() }
50 }
51
set_param(mut self, param: HiSysEventParam<'a>) -> Self52 fn set_param(mut self, param: HiSysEventParam<'a>) -> Self {
53 self.params.push(param);
54 self
55 }
56
write(self)57 fn write(self) {
58 let event_name = match self.event_type {
59 EventType::Fault => Self::ASSET_FAULT,
60 EventType::Statistic => Self::ASSET_STATISTIC,
61 _ => "UNKNOWN_EVENT",
62 };
63 write(Self::DOMAIN, event_name, self.event_type, self.params.as_slice());
64 }
65 }
66
67 const EXTRA_ATTRS: [Tag; 7] = [
68 Tag::SyncType,
69 Tag::Accessibility,
70 Tag::RequirePasswordSet,
71 Tag::AuthType,
72 Tag::OperationType,
73 Tag::ReturnType,
74 Tag::RequireAttrEncrypted,
75 ];
76
transfer_tag_to_string(tags: &[Tag], attributes: &AssetMap) -> Result<String>77 fn transfer_tag_to_string(tags: &[Tag], attributes: &AssetMap) -> Result<String> {
78 let mut ext_info = "".to_string();
79 for tag in tags {
80 if attributes.get(tag).is_none() {
81 continue;
82 }
83 let tag_value = match tag {
84 Tag::SyncType => format!("{}", attributes.get_num_attr(tag).unwrap_or(SyncType::default() as u32)),
85 Tag::Accessibility => format!("{}", attributes.get_enum_attr(tag).unwrap_or(Accessibility::default())),
86 Tag::RequirePasswordSet => format!("{}", attributes.get_bool_attr(tag).unwrap_or(false)),
87 Tag::AuthType => format!("{}", attributes.get_enum_attr(tag).unwrap_or(AuthType::default())),
88 Tag::ReturnType => format!("{}", attributes.get_enum_attr(tag).unwrap_or(ReturnType::default())),
89 Tag::RequireAttrEncrypted => format!("{}", attributes.get_bool_attr(tag).unwrap_or(false)),
90 Tag::OperationType => {
91 format!("{}", attributes.get_num_attr(tag).unwrap_or(OperationType::default() as u32))
92 },
93 _ => String::new(),
94 };
95 ext_info += &format!("{}:{};", tag, tag_value);
96 }
97 Ok(ext_info)
98 }
99
construct_ext_info(attributes: &AssetMap) -> Result<String>100 fn construct_ext_info(attributes: &AssetMap) -> Result<String> {
101 let tags = EXTRA_ATTRS.to_vec();
102 transfer_tag_to_string(&tags, attributes)
103 }
104
upload_statistic_system_event( calling_info: &CallingInfo, start_time: Instant, func_name: &str, ext_info: &str, )105 pub(crate) fn upload_statistic_system_event(
106 calling_info: &CallingInfo,
107 start_time: Instant,
108 func_name: &str,
109 ext_info: &str,
110 ) {
111 let duration = start_time.elapsed();
112 let owner_info = String::from_utf8_lossy(calling_info.owner_info()).to_string();
113 SysEvent::new(EventType::Statistic)
114 .set_param(build_str_param!(SysEvent::FUNCTION, func_name))
115 .set_param(build_number_param!(SysEvent::USER_ID, calling_info.user_id()))
116 .set_param(build_str_param!(SysEvent::CALLER, owner_info.clone()))
117 .set_param(build_number_param!(SysEvent::RUN_TIME, duration.as_millis() as u32))
118 .set_param(build_str_param!(
119 SysEvent::EXTRA,
120 format!(
121 "CallingUid={} ext_info={} caller_owner_type={}",
122 Skeleton::calling_uid(),
123 ext_info,
124 calling_info.owner_type()
125 )
126 ))
127 .write();
128 logi!("[INFO]CallingUid=[{}] ext_info=[{}]", Skeleton::calling_uid(), ext_info);
129 logi!(
130 "[INFO]Calling fun:[{}], user_id:[{}], caller:[{}], start_time:[{:?}], run_time:[{}]",
131 func_name,
132 calling_info.user_id(),
133 owner_info,
134 start_time,
135 duration.as_millis()
136 )
137 }
138
upload_fault_system_event( calling_info: &CallingInfo, start_time: Instant, func_name: &str, e: &AssetError, )139 pub(crate) fn upload_fault_system_event(
140 calling_info: &CallingInfo,
141 start_time: Instant,
142 func_name: &str,
143 e: &AssetError,
144 ) {
145 let owner_info = String::from_utf8_lossy(calling_info.owner_info()).to_string();
146 SysEvent::new(EventType::Fault)
147 .set_param(build_str_param!(SysEvent::FUNCTION, func_name))
148 .set_param(build_number_param!(SysEvent::USER_ID, calling_info.user_id()))
149 .set_param(build_str_param!(SysEvent::CALLER, owner_info.clone()))
150 .set_param(build_number_param!(SysEvent::ERROR_CODE, e.code as i32))
151 .set_param(build_str_param!(SysEvent::EXTRA, e.msg.clone()))
152 .write();
153 loge!(
154 "[ERROR]Calling fun:[{}], user_id:[{}], caller:[{}], start_time:[{:?}], error_code:[{}], error_msg:[{}]",
155 func_name,
156 calling_info.user_id(),
157 owner_info,
158 start_time,
159 e.code,
160 e.msg.clone()
161 );
162 }
163
upload_system_event<T>( result: Result<T>, calling_info: &CallingInfo, start_time: Instant, func_name: &str, attributes: &AssetMap, ) -> Result<T>164 pub(crate) fn upload_system_event<T>(
165 result: Result<T>,
166 calling_info: &CallingInfo,
167 start_time: Instant,
168 func_name: &str,
169 attributes: &AssetMap,
170 ) -> Result<T> {
171 let ext_info = construct_ext_info(attributes)?;
172 match &result {
173 Ok(_) => upload_statistic_system_event(calling_info, start_time, func_name, &ext_info),
174 Err(e) => upload_fault_system_event(calling_info, start_time, func_name, e),
175 }
176 result
177 }
178