/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
* 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.
*/
import relationalStore from '@ohos.data.relationalStore';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import commonEventManager from '@ohos.commonEventManager';
import { LogUtil } from '../utils/LogUtil';
import DatabaseManager from './DatabaseManager';
import {
BatteryListData,
BATTERYLIST_TABLE,
SQL_CREATE_BATTERY_LIST_TABLE,
SQL_DELET_OLD_BATTERYLIST_TABLE,
} from './BatteryListDataType';
import { HiSysEventUtil } from '../systemEvent/HiSysEventUtil';
import { HiSysRdbEventGroup } from '../systemEvent/BehaviorEventConsts';
const TAG: string = 'BatteryListDataManager:';
const POWER_DATA_LOADING: string = 'PowerDataLoading';
const RDB_CORRUPTION_ERROR_CODE: number = 14800011;
// RDB 数据库的初始化配置
export const STORE_CONFIG: relationalStore.StoreConfig = {
name: 'SettingsApp.db',
securityLevel: relationalStore.SecurityLevel.S1,
encrypt: false,
isSearchable: true,
haMode: relationalStore.HAMode.MAIN_REPLICA, //配置为双写备份
allowRebuild: true
};
export class BatteryListDataManager extends DatabaseManager {
public rdbStore: relationalStore.RdbStore | undefined;
/**
* 获取关系数据库存储对象
* 如果已初始化过,则直接返回之前获取的对象
* 如果没有初始化过,则使用接口获取对象,并执行数据库建表命令,如果表未创建,则会创建一张新的表
*
* @return 关系数据库存储对象
*/
async getRdb(context: common.Context): Promise<relationalStore.RdbStore> {
if (this.rdbStore) {
return this.rdbStore;
}
try {
LogUtil.info(`${TAG} getRdbStore start.`);
let rdbStore = await relationalStore.getRdbStore(context, STORE_CONFIG);
await rdbStore.executeSql(SQL_DELET_OLD_BATTERYLIST_TABLE);
await rdbStore.executeSql(SQL_CREATE_BATTERY_LIST_TABLE);
this.rdbStore = rdbStore;
LogUtil.info(`${TAG} getRdbStore success. rdbStoreBattery.version:${this.rdbStore?.version}`);
} catch (error) {
LogUtil.error(`${TAG} getRdbStore error. code:${error?.code} message:${error?.message}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
HiSysEventUtil.reportDefaultFaultEvent(HiSysRdbEventGroup.EVENT_NAME,
HiSysRdbEventGroup.SETTINGS_DATA_RDB_CORRUPTION);
await super.restoreRdb();
}
}
return this.rdbStore as relationalStore.RdbStore;
}
/**
* 电池耗电应用列表数据库 - 插入数据
*/
async batchInsertBatteryHistoryData(context: common.Context,
itemInfoList?: relationalStore.ValuesBucket[]): Promise<void> {
if (itemInfoList) {
const rdbStore = await this.getRdb(context);
let transaction: relationalStore.Transaction | undefined = undefined;
try {
transaction = await rdbStore.createTransaction();
if (transaction) {
const predicates = new relationalStore.RdbPredicates(BATTERYLIST_TABLE);
LogUtil.info(`${TAG} deleteBatteryHistoryData start.`);
// 先删除保证时序
let deleteNum: number = await transaction.delete(predicates);
LogUtil.info(`${TAG} batchInsertBatteryHistoryData start. deleted num: ${deleteNum}, need insert num:${itemInfoList?.length}`);
let insertNum: number = await transaction.batchInsert(BATTERYLIST_TABLE, itemInfoList);
LogUtil.info(`${TAG} batchInsertBatteryHistoryData success, insertNum: ${insertNum}`);
await transaction.commit();
LogUtil.info(`${TAG} commit list data success`);
this.sendListChartRefresh();
}
} catch (error) {
LogUtil.error(`${TAG} batchInsertBatteryHistoryData error, message: ${error?.message}, code: ${error?.code}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
HiSysEventUtil.reportDefaultFaultEvent(HiSysRdbEventGroup.EVENT_NAME,
HiSysRdbEventGroup.SETTINGS_DATA_RDB_CORRUPTION);
await super.restoreRdb();
}
if (transaction) {
transaction.rollback();
}
}
}
}
/**
* 电池耗电应用列表数据库 - 查询时间段数据
*/
async queryBatteryTimeAppData(context: common.Context,
startTimestamp: number, endTimestamp: number): Promise<BatteryListData[]> {
let listMap: Map<string, BatteryListData> = new Map();
let resultSet: relationalStore.ResultSet | undefined;
try {
const rdbStore = await this.getRdb(context);
const timestampPredicates = new relationalStore.RdbPredicates(BATTERYLIST_TABLE);
timestampPredicates.greaterThan('timestamp', startTimestamp).lessThanOrEqualTo('timestamp', endTimestamp);
LogUtil.info(`${TAG} queryBatteryTimeAppData start. startTime:${startTimestamp} endTime:${endTimestamp}`);
resultSet = await rdbStore.query(timestampPredicates);
LogUtil.info(`${TAG} queryBatteryTimeAppData success. resultSet.rowCount:${resultSet?.rowCount}`);
let batteryHistoryList = this.resultSet2List(resultSet);
batteryHistoryList.forEach(item => {
if (listMap.has(item.bundleName)) {
let hItem: BatteryListData = listMap.get(item.bundleName) as BatteryListData;
hItem.foregroundTime += item.foregroundTime;
hItem.foregroundPower += item.foregroundPower;
hItem.backgroundTime += item.backgroundTime;
hItem.backgroundPower += item.backgroundPower;
hItem.totalPower += item.totalPower;
listMap.set(item.bundleName, hItem);
} else {
listMap.set(item.bundleName, item);
}
})
} catch (error) {
LogUtil.error(`${TAG} queryBatteryTimeAppData error. code:${error?.code} message:${error?.message}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
HiSysEventUtil.reportDefaultFaultEvent(HiSysRdbEventGroup.EVENT_NAME,
HiSysRdbEventGroup.SETTINGS_DATA_RDB_CORRUPTION);
await super.restoreRdb();
}
} finally {
if (resultSet) {
resultSet && resultSet.close();
}
}
LogUtil.info(`${TAG} queryBatteryTimeAppData. listMap.size:${listMap?.size}`);
return Array.from(listMap.values());
}
/**
* 组装数据库结果 resultSet 转成 list 对象
*/
resultSet2List(resultSet: relationalStore.ResultSet): BatteryListData[] {
let batteryHistoryList: BatteryListData[] = [];
try {
while (resultSet.goToNextRow()) {
const timestamp = resultSet.getLong(resultSet.getColumnIndex('timestamp'));
const bundleName = resultSet.getString(resultSet.getColumnIndex('bundleName'));
const percentage = resultSet.getLong(resultSet.getColumnIndex('percentage'));
const totalPower = resultSet.getLong(resultSet.getColumnIndex('totalPower'));
const foregroundTime = resultSet.getLong(resultSet.getColumnIndex('foregroundTime'));
const foregroundPower = resultSet.getLong(resultSet.getColumnIndex('foregroundPower'));
const backgroundTime = resultSet.getLong(resultSet.getColumnIndex('backgroundTime'));
const backgroundPower = resultSet.getLong(resultSet.getColumnIndex('backgroundPower'));
const appType = resultSet.getLong(resultSet.getColumnIndex('appType'));
batteryHistoryList.push({
timestamp,
bundleName,
percentage,
totalPower,
foregroundTime,
foregroundPower,
backgroundTime,
backgroundPower,
appType,
});
}
resultSet.close();
} catch (error) {
resultSet.close();
LogUtil.error(`${TAG} getBatteryHistoryData error: ${(error as BusinessError).message}`);
}
return batteryHistoryList;
}
/**
* 电池耗电应用列表数据库 - 查询所有数据
*/
async queryBatteryHistoryData(context: common.Context): Promise<BatteryListData[]> {
const rdbStore = await this.getRdb(context);
let batteryHistoryList: BatteryListData[] = [];
let resultSet: relationalStore.ResultSet | undefined;
try {
const predicates = new relationalStore.RdbPredicates(BATTERYLIST_TABLE);
predicates.orderByDesc('timestamp');
LogUtil.info(`${TAG} queryBatteryHistoryData start.`);
resultSet = await rdbStore.query(predicates);
LogUtil.info(`${TAG} queryBatteryHistoryData success. resultSet.rowCount:${resultSet?.rowCount}`);
batteryHistoryList = this.resultSet2List(resultSet);
} catch (error) {
LogUtil.error(`${TAG} getBatteryHistoryData error, message: ${error?.message}, code: ${error?.code}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
HiSysEventUtil.reportDefaultFaultEvent(HiSysRdbEventGroup.EVENT_NAME,
HiSysRdbEventGroup.SETTINGS_DATA_RDB_CORRUPTION);
await super.restoreRdb();
}
} finally {
if (resultSet) {
resultSet && resultSet.close();
}
}
return batteryHistoryList;
}
/**
* 通知电池耗电列表重新查数据库来刷新数据
*/
sendListChartRefresh(): void {
try {
commonEventManager.publish(POWER_DATA_LOADING, (error: BusinessError) => {});
} catch (error) {
LogUtil.error(`commonEventManager createSubscriber error: ${error?.message}`);
}
}
}
export default new BatteryListDataManager();