Change-Id: Ie39a2afb0432dced7f9641cfd57ba8424580fa6a
This commit is contained in:
Cai Xincheng 2024-08-09 14:12:51 +08:00
commit e1b3383f1a
13 changed files with 90 additions and 46 deletions

View File

@ -17,7 +17,9 @@
"ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS",
"ohos.permission.GET_BUNDLE_INFO",
"ohos.permission.UPDATE_MIGRATE",
"ohos.permission.USE_CLOUD_DRIVE_SERVICE"
"ohos.permission.USE_CLOUD_DRIVE_SERVICE",
"ohos.permission.ATTEST_KEY",
"ohos.permission.USE_TRUSTED_RING"
],
"start-mode" : "condition",
"secon" : "u:r:asset_service:s0"

View File

@ -18,6 +18,7 @@
pub use asset_definition::Value;
use std::any::Any;
use std::collections::HashMap;
use ipc::parcel::MsgParcel;
/// Defines a type alias `ExtDbMap` as a `HashMap` with keys of type `&'static str` and values of type `Value`.
pub type ExtDbMap = HashMap<&'static str, Value>;
@ -80,6 +81,9 @@ pub trait IAssetPluginCtx: Any + Sync + Send + std::panic::RefUnwindSafe {
/// Adds an asset to the database.
fn add(&mut self, attributes: &ExtDbMap) -> Result<i32, u32>;
/// Add an asset with replace.
fn replace(&mut self, condition: &ExtDbMap, attributes: &ExtDbMap) -> std::result::Result<(), u32>;
/// Queries the asset database.
fn query(&mut self, attributes: &ExtDbMap) -> Result<Vec<ExtDbMap>, u32>;
@ -118,4 +122,7 @@ pub trait IAssetPlugin: Any + Sync + Send + std::panic::RefUnwindSafe {
/// Process the event.
fn process_event(&self, event_type: EventType, params: &ExtDbMap) -> Result<(), u32>;
/// Redirect request.
fn redirect_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> Result<(), i32>;
}

View File

@ -22,7 +22,6 @@ edition = "2021"
hilog_rust = { git = "https://gitee.com/openharmony/hiviewdfx_hilog.git" }
samgr = { git = "https://gitee.com/openharmony/systemabilitymgr_samgr.git" }
system_ability_fwk = { git = "https://gitee.com/openharmony/systemabilitymgr_safwk" }
hitrace_meter_rust = { git = "https://gitee.com/openharmony/hiviewdfx_hitrace.git" }
hisysevent = { git = "https://gitee.com/openharmony/hiviewdfx_hisysevent.git" }
ipc = { git = "https://gitee.com/openharmony/communication_ipc" }
ylong_runtime = { git = "https://gitee.com/openharmony/commonlibrary_rust_ylong_runtime.git", features = ["full"] }

View File

@ -264,7 +264,7 @@ fn backup_db_key_cipher_if_exists(user_id: i32) -> Result<()> {
}
extern "C" {
fn GetUserIds(userIdsPtr: *mut i32, userIdsSize: *mut i16) -> i32;
fn GetUserIds(userIdsPtr: *mut i32, userIdsSize: *mut u16) -> i32;
}
fn backup_all_db(start_time: &Instant) -> Result<()> {
@ -281,9 +281,11 @@ fn backup_all_db(start_time: &Instant) -> Result<()> {
// Backup all ce db and db key cipher if exists. (todo?: backup ce db if accessible)
unsafe {
let mut user_ids: Vec<i32> = Vec::new();
/* Temporarily allocate at least 256 spaces for user ids.
If the number of user ids exceeds 256, this method(with_capacity) will automatically allocate more spaces.*/
let mut user_ids: Vec<i32> = Vec::with_capacity(256);
let user_ids_ptr = user_ids.as_mut_ptr();
let mut user_ids_size: i16 = 0;
let mut user_ids_size: u16 = 0;
let user_ids_size_ptr = &mut user_ids_size;
let ret = GetUserIds(user_ids_ptr, user_ids_size_ptr);
if ret != SUCCESS {
@ -293,11 +295,11 @@ fn backup_all_db(start_time: &Instant) -> Result<()> {
for user_id in user_ids_slice.iter() {
if let Err(e) = backup_ce_db_if_exists(*user_id) {
let calling_info = CallingInfo::new_self();
upload_fault_system_event(&calling_info, *start_time, &format!("backup_ce_db_{}", user_id), &e);
upload_fault_system_event(&calling_info, *start_time, &format!("backup_ce_db_{}", *user_id), &e);
}
if let Err(e) = backup_db_key_cipher_if_exists(*user_id) {
let calling_info = CallingInfo::new_self();
upload_fault_system_event(&calling_info, *start_time, &format!("backup_db_key_cipher_{}", user_id), &e);
upload_fault_system_event(&calling_info, *start_time, &format!("backup_db_key_cipher_{}", *user_id), &e);
}
}
};

View File

@ -81,7 +81,7 @@ fn encrypt_db_key(calling_info: &CallingInfo, db_key: &Vec<u8>) -> Result<Vec<u8
Ok(db_key_cipher)
}
pub fn get_db_key(calling_info: &CallingInfo) -> Result<Vec<u8>>
fn get_db_key(calling_info: &CallingInfo) -> Result<Vec<u8>>
{
match asset_file_operator::is_db_key_cipher_file_exist(calling_info.user_id()) {
Ok(true) => {

View File

@ -32,8 +32,7 @@ use asset_sdk::{
use crate::{unload_handler::DELAYED_UNLOAD_TIME_IN_SEC, unload_sa, AssetService};
const UPGRADE_CODE: u32 = 18100;
const UPGRADE_TOKEN: &str = "OHOS.Updater.RestoreData";
const REDIRECT_START_CODE: u32 = 200;
impl RemoteStub for AssetService {
fn on_remote_request(
@ -46,7 +45,7 @@ impl RemoteStub for AssetService {
self.system_ability.cancel_idle();
unload_sa(DELAYED_UNLOAD_TIME_IN_SEC as u64);
if code == UPGRADE_CODE {
if code >= REDIRECT_START_CODE {
return on_extension_request(self, code, data, reply);
}
@ -126,29 +125,20 @@ fn on_remote_request(stub: &AssetService, code: u32, data: &mut MsgParcel, reply
}
}
fn on_extension_request(_stub: &AssetService, _code: u32, data: &mut MsgParcel, _reply: &mut MsgParcel) -> i32 {
match data.read_interface_token() {
Ok(interface_token) if interface_token == UPGRADE_TOKEN => {},
_ => {
loge!("[FATAL][SA]Invalid interface token.");
return IpcStatusCode::Failed as i32;
},
};
match data.read::<i32>() {
Ok(user_id) => {
logi!("[INFO]User id is {}.", user_id);
if let Ok(load) = AssetPlugin::get_instance().load_plugin() {
let mut params = ExtDbMap::new();
params.insert(PARAM_NAME_USER_ID, Value::Number(user_id as u32));
match load.process_event(EventType::OnDeviceUpgrade, &params) {
Ok(()) => logi!("process device upgrade event success."),
Err(code) => loge!("process device upgrade event failed, code: {}", code),
}
}
IPC_SUCCESS as i32
},
_ => IpcStatusCode::Failed as i32,
fn on_extension_request(_stub: &AssetService, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 {
if let Ok(load) = AssetPlugin::get_instance().load_plugin() {
match load.redirect_request(code, data, reply) {
Ok(()) => {
logi!("process redirect request success.");
return IPC_SUCCESS as i32;
},
Err(code) => {
loge!("process redirect request failed, code: {}", code);
return code as i32;
},
}
}
IpcStatusCode::Failed as i32
}
fn asset_err_handle(e: AssetError) -> IpcStatusCode {

View File

@ -26,7 +26,8 @@ use asset_log::{loge, logi};
use crate::{
statement::Statement,
table::Table,
types::{column, sqlite_err_handle, DbMap, QueryOptions, COLUMN_INFO, SQLITE_OK, TABLE_NAME, UPGRADE_COLUMN_INFO},
types::{column, sqlite_err_handle, DbMap, QueryOptions, COLUMN_INFO, SQLITE_OK, TABLE_NAME, UPGRADE_COLUMN_INFO_V2,
UPGRADE_COLUMN_INFO, DB_UPGRADE_VERSION_V1, DB_UPGRADE_VERSION_V2, DB_UPGRADE_VERSION},
};
extern "C" {
@ -119,7 +120,7 @@ impl Database {
let _lock = db.db_lock.mtx.lock().unwrap();
db.open_and_restore(db_key)?;
db.restore_if_exec_fail(|e: &Table| e.create(COLUMN_INFO))?;
db.upgrade(1, |_, _, _| Ok(()))?;
db.upgrade(DB_UPGRADE_VERSION, |_, _, _| Ok(()))?;
Ok(db)
}
@ -218,12 +219,18 @@ impl Database {
/// Upgrade database to new version.
#[allow(dead_code)]
pub fn upgrade(&mut self, ver: u32, callback: UpgradeDbCallback) -> Result<()> {
let version_old = self.get_db_version()?;
let mut version_old = self.get_db_version()?;
logi!("current database version: {}", version_old);
if version_old >= ver {
return Ok(());
}
self.restore_if_exec_fail(|e: &Table| e.upgrade(ver, UPGRADE_COLUMN_INFO))?;
if version_old == DB_UPGRADE_VERSION_V1 {
self.restore_if_exec_fail(|e: &Table| e.upgrade(DB_UPGRADE_VERSION_V2, UPGRADE_COLUMN_INFO_V2))?;
version_old += 1;
}
if version_old == DB_UPGRADE_VERSION_V2 {
self.restore_if_exec_fail(|e: &Table| e.upgrade(DB_UPGRADE_VERSION, UPGRADE_COLUMN_INFO))?;
}
callback(self, version_old, ver)
}

View File

@ -26,7 +26,7 @@ use crate::{
database::Database,
statement::Statement,
transaction::Transaction,
types::{ColumnInfo, DbMap, QueryOptions, UpgradeColumnInfo, SQLITE_ROW},
types::{ColumnInfo, DbMap, QueryOptions, UpgradeColumnInfo, SQLITE_ROW, DB_UPGRADE_VERSION},
};
extern "C" {
@ -237,7 +237,7 @@ impl<'a> Table<'a> {
sql.push_str(");");
let mut trans = Transaction::new(self.db);
trans.begin()?;
if self.db.exec(sql.as_str()).is_ok() && self.db.set_version(1).is_ok() {
if self.db.exec(sql.as_str()).is_ok() && self.db.set_version(DB_UPGRADE_VERSION).is_ok() {
trans.commit()
} else {
trans.rollback()

View File

@ -25,10 +25,19 @@ pub type DbMap = HashMap<&'static str, Value>;
/// Table name of asset database.
pub const TABLE_NAME: &str = "asset_table";
/// Version V1 number for upgrade database
pub const DB_UPGRADE_VERSION_V1: u32 = 0;
/// Version V2 number for upgrade database
pub const DB_UPGRADE_VERSION_V2: u32 = 1;
/// Latest version number for upgrade database
pub const DB_UPGRADE_VERSION: u32 = 2;
/// Version 1 number
pub const DB_DATA_VERSION_V1: u32 = 1;
/// Version 2 number
pub const DB_DATA_VERSION_V2: u32 = 2;
/// Latest data version number.
pub const DB_DATA_VERSION: u32 = 2;
pub const DB_DATA_VERSION: u32 = 3;
/// Column name of asset database.
pub mod column {
/// Column name of the primary key Id.
@ -91,6 +100,8 @@ pub mod column {
pub const LOCAL_STATUS: &str = "LocalStatus";
/// Column name of the fourth normal local data label.
pub const SYNC_STATUS: &str = "SyncStatus";
/// Column name of the ext data info.
pub const EXT_INFO: &str = "ExtInfo";
}
#[repr(C)]
@ -132,6 +143,7 @@ pub(crate) const COLUMN_INFO: &[ColumnInfo] = &[
ColumnInfo { name: column::CLOUD_VERSION, data_type: DataType::Bytes, is_primary_key: false, not_null: false },
ColumnInfo { name: column::LOCAL_STATUS, data_type: DataType::Number, is_primary_key: false, not_null: true },
ColumnInfo { name: column::SYNC_STATUS, data_type: DataType::Number, is_primary_key: false, not_null: true },
ColumnInfo { name: column::EXT_INFO, data_type: DataType::Bytes, is_primary_key: false, not_null: false },
];
pub(crate) struct UpgradeColumnInfo {
@ -139,7 +151,7 @@ pub(crate) struct UpgradeColumnInfo {
pub(crate) default_value: Option<Value>,
}
pub(crate) const UPGRADE_COLUMN_INFO: &[UpgradeColumnInfo] = &[
pub(crate) const UPGRADE_COLUMN_INFO_V2: &[UpgradeColumnInfo] = &[
UpgradeColumnInfo {
base_info: ColumnInfo {
name: column::NORMAL_LOCAL1,
@ -214,6 +226,18 @@ pub(crate) const UPGRADE_COLUMN_INFO: &[UpgradeColumnInfo] = &[
},
];
pub(crate) const UPGRADE_COLUMN_INFO: &[UpgradeColumnInfo] = &[
UpgradeColumnInfo {
base_info: ColumnInfo {
name: column::EXT_INFO,
data_type: DataType::Bytes,
is_primary_key: false,
not_null: false,
},
default_value: None,
},
];
/// Options for batch query.
#[repr(C)]
pub struct QueryOptions {

View File

@ -24,7 +24,7 @@ extern "C" {
bool GetUserIdByUid(uint64_t uid, uint32_t *userId);
bool IsUserIdExist(int32_t userId, bool *exist);
int32_t GetUserIds(int32_t *userIdsPtr, int16_t *userIdsSize);
int32_t GetUserIds(int32_t *userIdsPtr, uint16_t *userIdsSize);
#ifdef __cplusplus
}

View File

@ -44,7 +44,7 @@ bool IsUserIdExist(int32_t userId, bool *exist)
return true;
}
int32_t GetUserIds(int32_t *userIdsPtr, int16_t *userIdsSize)
int32_t GetUserIds(int32_t *userIdsPtr, uint16_t *userIdsSize)
{
std::vector<OHOS::AccountSA::OsAccountInfo> accountInfos = {};
int32_t ret = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(accountInfos);
@ -59,8 +59,10 @@ int32_t GetUserIds(int32_t *userIdsPtr, int16_t *userIdsSize)
std::vector<int32_t> userIdsVec = { 0 };
std::transform(accountInfos.begin(), accountInfos.end(), std::back_inserter(userIdsVec),
[](auto &iter) { return iter.GetLocalId(); });
userIdsPtr = userIdsVec.data();
*userIdsSize = static_cast<int16_t>(userIdsVec.size());
for (size_t i = 0; i < userIdsVec.size(); i++) {
userIdsPtr[i] = userIdsVec[i];
}
*userIdsSize = static_cast<uint16_t>(userIdsVec.size());
return ASSET_SUCCESS;
}

View File

@ -22,3 +22,6 @@ edition = "2021"
asset_common = { path = "../common" }
asset_definition = { path = "../../frameworks/definition" }
asset_log = { path = "../../frameworks/os_dependency/log" }
asset_sdk = { path = "../../interfaces/inner_api/rs" }
asset_db_operator = { path = "../db_operator" }
asset_file_operator = { path = "../../frameworks/os_dependency/file" }

View File

@ -14,7 +14,7 @@
*/
use asset_common::Counter;
use asset_db_operator::{database::get_path, database::Database};
use asset_db_operator::database::{get_path, Database};
use asset_definition::{log_throw_error, ErrCode, Result};
use asset_log::{loge, logi};
use asset_sdk::plugin_interface::{ExtDbMap, IAssetPlugin, IAssetPluginCtx};
@ -122,6 +122,14 @@ impl IAssetPluginCtx for AssetContext {
.map_err(|e| e.code as u32)
}
fn replace(&mut self, condition: &ExtDbMap, attributes: &ExtDbMap) -> std::result::Result<(), u32> {
self.data_base
.as_mut()
.ok_or(ErrCode::InvalidArgument as u32)?
.replace_datas(condition, false, attributes)
.map_err(|e| e.code as u32)
}
/// Queries the asset database.
fn query(&mut self, attributes: &ExtDbMap) -> std::result::Result<Vec<ExtDbMap>, u32> {
self.data_base