• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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