* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::{process_info::ProcessInfoDetail, OwnerType, ProcessInfo, GROUP_SEPARATOR};
use asset_definition::Value;
#[derive(Clone)]
#[derive(PartialEq, Eq)]
#[derive(Hash)]
pub struct Group {
pub developer_id: Vec<u8>,
pub group_id: Vec<u8>,
}
#[derive(Clone)]
#[derive(PartialEq, Eq)]
#[derive(Hash)]
pub struct CallingInfo {
user_id: i32,
owner_type: OwnerType,
owner_info: Vec<u8>,
group: Option<Group>,
}
impl CallingInfo {
pub fn new_self() -> Self {
Self::new(0, OwnerType::Native, "asset_service_8100".as_bytes().to_vec(), None)
}
pub fn new(user_id: i32, owner_type: OwnerType, owner_info: Vec<u8>, group: Option<Group>) -> Self {
Self { user_id, owner_type, owner_info, group }
}
pub fn build(specific_user_id: Option<Value>, process_info: &ProcessInfo) -> Self {
let mut user_id = process_info.user_id;
if let Some(Value::Number(specific_user_id)) = specific_user_id {
user_id = specific_user_id;
};
let mut owner_info = Vec::new();
match &process_info.process_info_detail {
ProcessInfoDetail::Hap(hap_info) => {
owner_info.extend_from_slice(&hap_info.app_id);
owner_info.extend_from_slice("_".as_bytes());
owner_info.extend_from_slice(hap_info.app_index.to_string().as_bytes());
let group = match (&hap_info.developer_id, &hap_info.group_id) {
(Some(developer_id), Some(group_id)) => {
Some(Group { developer_id: developer_id.to_vec(), group_id: group_id.to_vec() })
},
_ => None,
};
CallingInfo { user_id: user_id as i32, owner_type: process_info.owner_type, owner_info, group }
},
ProcessInfoDetail::Native(native_info) => {
owner_info.append(&mut process_info.process_name.clone());
owner_info.append(&mut "_".to_string().as_bytes().to_vec());
owner_info.append(&mut native_info.uid.to_string().as_bytes().to_vec());
CallingInfo { user_id: user_id as i32, owner_type: process_info.owner_type, owner_info, group: None }
},
}
}
pub fn owner_type(&self) -> u32 {
self.owner_type as u32
}
pub fn owner_type_enum(&self) -> OwnerType {
self.owner_type
}
pub fn owner_info(&self) -> &Vec<u8> {
&self.owner_info
}
pub fn user_id(&self) -> i32 {
self.user_id
}
pub fn developer_id(&self) -> Option<&Vec<u8>> {
match &self.group {
Some(group) => Some(&group.developer_id),
_ => None,
}
}
pub fn group_id(&self) -> Option<&Vec<u8>> {
match &self.group {
Some(group) => Some(&group.group_id),
_ => None,
}
}
pub fn group(&self) -> Option<Vec<u8>> {
match &self.group {
Some(group) => {
let mut group_vec: Vec<u8> = Vec::new();
group_vec.extend(group.developer_id.clone());
group_vec.push(GROUP_SEPARATOR as u8);
group_vec.extend(group.group_id.clone());
Some(group_vec)
},
_ => None,
}
}
pub fn app_index(&self) -> u32 {
match self.owner_type_enum() {
OwnerType::Hap | OwnerType::HapGroup => {
let owner_info_str = String::from_utf8_lossy(self.owner_info()).to_string();
let owner_info_vec: Vec<_> = owner_info_str.split('_').collect();
match owner_info_vec.last().unwrap().parse::<u32>() {
Ok(num) => num,
Err(_e) => 0,
}
},
OwnerType::Native => 0,
}
}
}
#[cfg(test)]
use crate::process_info::{HapInfo, NativeInfo};
#[test]
fn test_build_callig_info_specific_and_hap() {
let specific_user_id = 100;
let process_name = "test_process".as_bytes().to_vec();
let app_id = "test_app_id".as_bytes().to_vec();
let app_index = 0;
let group_id = None;
let developer_id = None;
let process_info = ProcessInfo {
user_id: 0,
owner_type: OwnerType::Hap,
process_name,
process_info_detail: ProcessInfoDetail::Hap(HapInfo { app_id, app_index, group_id, developer_id }),
};
let calling_info = CallingInfo::build(Some(Value::Number(specific_user_id)), &process_info);
assert_eq!(calling_info.user_id(), specific_user_id as i32);
let owner_info = "test_app_id_0".as_bytes().to_vec();
assert_eq!(calling_info.owner_info(), &owner_info);
}
#[test]
fn test_build_callig_info_hap() {
let process_name = "test_process".as_bytes().to_vec();
let app_id = "test_app_id".as_bytes().to_vec();
let app_index = 0;
let user_id = 0;
let group_id = None;
let developer_id = None;
let process_info = ProcessInfo {
user_id,
owner_type: OwnerType::Hap,
process_name,
process_info_detail: ProcessInfoDetail::Hap(HapInfo { app_id, app_index, group_id, developer_id }),
};
let calling_info = CallingInfo::build(None, &process_info);
assert_eq!(calling_info.user_id(), user_id as i32);
let owner_info = "test_app_id_0".as_bytes().to_vec();
assert_eq!(calling_info.owner_info(), &owner_info);
}
#[test]
fn test_build_callig_info_native() {
let process_name = "test_process".as_bytes().to_vec();
let user_id = 0;
let uid = 999;
let process_info = ProcessInfo {
user_id,
owner_type: OwnerType::Native,
process_name,
process_info_detail: ProcessInfoDetail::Native(NativeInfo { uid }),
};
let calling_info = CallingInfo::build(None, &process_info);
assert_eq!(calling_info.user_id(), user_id as i32);
let owner_info = "test_process_999".as_bytes().to_vec();
assert_eq!(calling_info.owner_info(), &owner_info);
}
#[test]
fn test_build_callig_info_specific_and_native() {
let specific_user_id = 100;
let process_name = "test_process".as_bytes().to_vec();
let user_id = 0;
let uid = 999;
let process_info = ProcessInfo {
user_id,
owner_type: OwnerType::Native,
process_name,
process_info_detail: ProcessInfoDetail::Native(NativeInfo { uid }),
};
let calling_info = CallingInfo::build(Some(Value::Number(specific_user_id)), &process_info);
assert_eq!(calling_info.user_id(), specific_user_id as i32);
let owner_info = "test_process_999".as_bytes().to_vec();
assert_eq!(calling_info.owner_info(), &owner_info);
}