/*
* 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 type Want from '@ohos.application.Want';
import ServiceExtension from '@ohos.app.ability.ServiceExtensionAbility';
import ContactsDataService from './../serivce/ContactsDataService';
import LogUtils from '../common/utils/LogUtils';
import hiTraceMeter from '@ohos.hiTraceMeter';
import { checkContactTask, manualMergeContactTask } from './../serivce/RepeatContactHandleService';
import HandleUniqueKeyService from '../serivce/HandleUniqueKeyService';
import { Stub } from '../WorkScheduler/Common';
import ContactAggregator from '../aggregation/ContactAggregator';
import { StringUtil } from '../common/utils/StringUtil';
const TAG = 'ServiceAbility';
export default class ServiceAbility extends ServiceExtension {
public contactsDataService: ContactsDataService | undefined = undefined;
public timestamp: number = 0;
public workerId: number = 0;
public syncTimestamp: number = 0;
public syncWorkerId: number = 0;
public traceServiceCreate: number = 1001;
public athousandMs = 1000;
public oneHundredMs: number = 5000;
public fiveThousandMs: number = 5000;
/**
* ServiceExtension 初始化时,初始化业务处理类 ContactsDataService 的单例,并设置其上下文
* @param want
*/
onCreate(want: Want): void {
LogUtils.i(TAG, 'onCreate ContactsData service');
hiTraceMeter.startTrace('serviceonCreate', this.traceServiceCreate);
this.contactsDataService = ContactsDataService.getInstance();
this.contactsDataService.init(this.context);
hiTraceMeter.finishTrace('serviceonCreate', this.traceServiceCreate);
}
onConnect(want: Want): Stub {
LogUtils.i(TAG, 'onConnect ContactsData service');
return new Stub('ServiceAbility');
}
onDisconnect(): void {
LogUtils.i(TAG, 'onDisconnect ContactsData service');
}
onRequest(want: Want, startId: number): void {
let insertParam: string = want.parameters?.insert;
let updateParam: string = want.parameters?.update;
let deleteParam: string = want.parameters?.delete;
let compareCloudAndRawContact: string = want.parameters?.compareCloudAndRawContact;
let refreshContact: string = want.parameters?.refreshContact;
let mergeContactArgs: string = want.parameters?.mergeContactArgs;
LogUtils.w(TAG, 'onRequest ContactsData service insertParam length' + insertParam?.length + ' updateParam length' +
updateParam?.length +
' deleteParam length' + deleteParam?.length + ' compareCloudAndRawContact ' + compareCloudAndRawContact +
' refreshContact ' + refreshContact +
' mergeContactArgs ' + want.parameters?.mergeContactArgs);
if (refreshContact === 'mergeContact') {
// 应用触发全量去重,会通过 datashare 调到这里,克隆 云同步是过程中去重,不会调这里
LogUtils.i(TAG, 'start mergeContact task');
if (!ContactsDataService.getInstance().isMergingContact()) { //如果当前没在去重,才去调用去重方法,保证去重任务不会重复执行
ContactsDataService.getInstance().setMergingContact(true);
let task: Promise<boolean> = Promise.resolve(true);
// 合并联系人
if (want.parameters?.mergeContactArgs && want.parameters?.mergeContactArgs !== 'manual') {
task = manualMergeContactTask(this.context!, want.parameters?.mergeContactArgs);
} else {
let isAutoMerge: boolean = StringUtil.isEmpty(want.parameters?.mergeContactArgs);
task = HandleUniqueKeyService.getInstance().waitForCalcUniqueKeyEnd(this.context)
.then(() => {
// 检查重复联系人
return checkContactTask(this.context!, isAutoMerge);
});
}
task.then(() => {//调用去重方法
ContactsDataService.getInstance().setMergingContact(false);
}).catch((error: Error) => {
ContactsDataService.getInstance().setMergingContact(false);
LogUtils.e(TAG, 'checkContactTask error:' + error.message);
});
}
} else if (refreshContact === 'splitRawContactAfterDel') {
LogUtils.i(TAG, 'start splitRawContactAfterDel task');
ContactAggregator.getInstance().doSplitAggregationContactAfterDel(want.parameters?.mergeContactArgs)
.catch((error: Error) => {
LogUtils.e(TAG, 'splitRawContactAfterDel error:%s' + error?.message + ', stack: ' + error?.stack);
});
} else if (refreshContact === 'localRestoreContact') {
LogUtils.i(TAG, 'start localRestoreContact task');
// 本地恢复联系人
ContactsDataService.getInstance().localRestoreContact(want.parameters?.mergeContactArgs)
.catch((error: Error) => {
LogUtils.e(TAG, 'localRestoreContact error:%s' + error?.message + ', stack: ' + error?.stack);
});
} else {
let nowTimeStamp = new Date().getTime();
if (nowTimeStamp - this.timestamp < this.fiveThousandMs) {
clearTimeout(this.workerId)
}
this.timestamp = nowTimeStamp;
this.workerId = setTimeout(() => {
ContactsDataService.getInstance().contactsDataChange(this.context).catch((error: Error) => {
LogUtils.e(TAG, 'local contacts change contactsDataChange error:%s' + error?.message + ', stack: ' + error?.stack);
})
}, this.fiveThousandMs); // 如果短期内数据变化频繁,顺延定时器,让这段逻辑不会并行或者多次执行
}
}
onDestroy(): void {
LogUtils.i(TAG, 'onDestroy ContactsData service');
}
}