18779efd5Sopenharmony_ci/** 28779efd5Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 38779efd5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48779efd5Sopenharmony_ci * you may not use this file except in compliance with the License. 58779efd5Sopenharmony_ci * You may obtain a copy of the License at 68779efd5Sopenharmony_ci * 78779efd5Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88779efd5Sopenharmony_ci * 98779efd5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108779efd5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118779efd5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128779efd5Sopenharmony_ci * See the License for the specific language governing permissions and 138779efd5Sopenharmony_ci * limitations under the License. 148779efd5Sopenharmony_ci */ 158779efd5Sopenharmony_ci 168779efd5Sopenharmony_ciimport { HiLog, sharedPreferencesUtils } from 'common'; 178779efd5Sopenharmony_ciimport { MissedCallNotifier, MissedCallNotifyData } from './MissedCallNotifier' 188779efd5Sopenharmony_ciimport { CallLogRepository } from '../repo/CallLogRepository'; 198779efd5Sopenharmony_ciimport { ContactRepository } from '../../../../../../feature/contact/src/main/ets/repo/ContactRepository'; 208779efd5Sopenharmony_ciimport { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil'; 218779efd5Sopenharmony_ciimport { CallLog } from '../entity/CallLog' 228779efd5Sopenharmony_ci 238779efd5Sopenharmony_ciconst TAG = 'MissedCallService'; 248779efd5Sopenharmony_ciconst LAST_MISSED_ID: string = 'Last_Missed_id' 258779efd5Sopenharmony_ciconst PREFERENCE_NAME: string = 'CONTACT_PREFERENCE'; 268779efd5Sopenharmony_ci 278779efd5Sopenharmony_ciexport class MissedCallService { 288779efd5Sopenharmony_ci private static sInstance: MissedCallService = undefined; 298779efd5Sopenharmony_ci private context: Context = undefined; 308779efd5Sopenharmony_ci private lastMissedId = -1; 318779efd5Sopenharmony_ci private onCallLogChanged = () => { 328779efd5Sopenharmony_ci if (this.lastMissedId != -1) { 338779efd5Sopenharmony_ci HiLog.i(TAG, 'onCallLogChanged lastMissedId:' + this.lastMissedId); 348779efd5Sopenharmony_ci this.sendMissedCallNotify(this.lastMissedId); 358779efd5Sopenharmony_ci } 368779efd5Sopenharmony_ci this.unRegisterDataChangeObserver(); 378779efd5Sopenharmony_ci } 388779efd5Sopenharmony_ci 398779efd5Sopenharmony_ci /** 408779efd5Sopenharmony_ci * getInstance for MissedCallService 418779efd5Sopenharmony_ci */ 428779efd5Sopenharmony_ci public static getInstance() { 438779efd5Sopenharmony_ci if (!MissedCallService.sInstance || MissedCallService.sInstance == undefined) { 448779efd5Sopenharmony_ci MissedCallService.sInstance = new MissedCallService(); 458779efd5Sopenharmony_ci } 468779efd5Sopenharmony_ci return MissedCallService.sInstance; 478779efd5Sopenharmony_ci } 488779efd5Sopenharmony_ci 498779efd5Sopenharmony_ci /** 508779efd5Sopenharmony_ci * init 518779efd5Sopenharmony_ci * 528779efd5Sopenharmony_ci * @param ctx context needed init 538779efd5Sopenharmony_ci */ 548779efd5Sopenharmony_ci public init(ctx: Context) { 558779efd5Sopenharmony_ci this.context = ctx; 568779efd5Sopenharmony_ci sharedPreferencesUtils.init(ctx); 578779efd5Sopenharmony_ci MissedCallNotifier.getInstance().init(ctx); 588779efd5Sopenharmony_ci CallLogRepository.getInstance().init(ctx); 598779efd5Sopenharmony_ci ContactRepository.getInstance().init(ctx); 608779efd5Sopenharmony_ci } 618779efd5Sopenharmony_ci 628779efd5Sopenharmony_ci /** 638779efd5Sopenharmony_ci * updateAllMissedCallNotifications 648779efd5Sopenharmony_ci */ 658779efd5Sopenharmony_ci public async updateAllMissedCallNotifications() { 668779efd5Sopenharmony_ci HiLog.i(TAG, 'updateMissedCallNotifications'); 678779efd5Sopenharmony_ci MissedCallNotifier.getInstance().cancelAllNotification(); 688779efd5Sopenharmony_ci this.sendMissedCallNotify(); 698779efd5Sopenharmony_ci } 708779efd5Sopenharmony_ci 718779efd5Sopenharmony_ci /** 728779efd5Sopenharmony_ci * updateMissedCallNotifications 738779efd5Sopenharmony_ci */ 748779efd5Sopenharmony_ci public async updateMissedCallNotifications() { 758779efd5Sopenharmony_ci if (this.lastMissedId == -1) { 768779efd5Sopenharmony_ci this.lastMissedId = await this.getLastNotificationId(); 778779efd5Sopenharmony_ci } 788779efd5Sopenharmony_ci this.registerDataChangeObserver(); 798779efd5Sopenharmony_ci HiLog.i(TAG, 'updateMissedCallNotifications, lastMissedId:' + this.lastMissedId); 808779efd5Sopenharmony_ci this.sendMissedCallNotify(this.lastMissedId); 818779efd5Sopenharmony_ci } 828779efd5Sopenharmony_ci 838779efd5Sopenharmony_ci /** 848779efd5Sopenharmony_ci * 858779efd5Sopenharmony_ci * Unread missed call notification 868779efd5Sopenharmony_ci */ 878779efd5Sopenharmony_ci public async unreadCallNotification(map:Map<string,string>) { 888779efd5Sopenharmony_ci MissedCallNotifier.getInstance().sendUnreadCallNotification(map); 898779efd5Sopenharmony_ci } 908779efd5Sopenharmony_ci 918779efd5Sopenharmony_ci /** 928779efd5Sopenharmony_ci * cancelMissedNotificationAction 938779efd5Sopenharmony_ci * 948779efd5Sopenharmony_ci * @param data MissedCallNotifyData need cancel notify 958779efd5Sopenharmony_ci */ 968779efd5Sopenharmony_ci public async cancelMissedNotificationAction(data: MissedCallNotifyData) { 978779efd5Sopenharmony_ci HiLog.i(TAG, `cancelMissedNotificationAction, ${JSON.stringify(data)}`); 988779efd5Sopenharmony_ci MissedCallNotifier.getInstance().cancelNotificationById(data.id, data.count); 998779efd5Sopenharmony_ci CallLogRepository.getInstance().markMissedCallLogAsRead(data.phoneNumber); 1008779efd5Sopenharmony_ci } 1018779efd5Sopenharmony_ci 1028779efd5Sopenharmony_ci /** 1038779efd5Sopenharmony_ci * cancelAllMissedNotificationAction 1048779efd5Sopenharmony_ci */ 1058779efd5Sopenharmony_ci public async cancelAllMissedNotificationAction() { 1068779efd5Sopenharmony_ci let unreadMissed = await MissedCallNotifier.getInstance().getMissedBadgeNumber() 1078779efd5Sopenharmony_ci if (unreadMissed > 0) { 1088779efd5Sopenharmony_ci HiLog.i(TAG, `cancelAllMissedNotificationAction cancel all`); 1098779efd5Sopenharmony_ci MissedCallNotifier.getInstance().cancelAllNotification(); 1108779efd5Sopenharmony_ci CallLogRepository.getInstance().markMissedCallLogAsRead(); 1118779efd5Sopenharmony_ci } 1128779efd5Sopenharmony_ci } 1138779efd5Sopenharmony_ci 1148779efd5Sopenharmony_ci private constructor() { 1158779efd5Sopenharmony_ci } 1168779efd5Sopenharmony_ci 1178779efd5Sopenharmony_ci private getContext() { 1188779efd5Sopenharmony_ci if (this.context && this.context != undefined) { 1198779efd5Sopenharmony_ci return this.context; 1208779efd5Sopenharmony_ci } 1218779efd5Sopenharmony_ci return globalThis.context; 1228779efd5Sopenharmony_ci } 1238779efd5Sopenharmony_ci 1248779efd5Sopenharmony_ci private registerDataChangeObserver() { 1258779efd5Sopenharmony_ci HiLog.i(TAG, 'registerDataChangeObserver'); 1268779efd5Sopenharmony_ci CallLogRepository.getInstance().registerDataChangeObserver(this.onCallLogChanged); 1278779efd5Sopenharmony_ci } 1288779efd5Sopenharmony_ci 1298779efd5Sopenharmony_ci private unRegisterDataChangeObserver() { 1308779efd5Sopenharmony_ci HiLog.i(TAG, 'unRegisterDataChangeObserver'); 1318779efd5Sopenharmony_ci CallLogRepository.getInstance().unRegisterDataChangeObserver(this.onCallLogChanged); 1328779efd5Sopenharmony_ci } 1338779efd5Sopenharmony_ci 1348779efd5Sopenharmony_ci private async getLastNotificationId() { 1358779efd5Sopenharmony_ci return <number> await sharedPreferencesUtils.getFromPreferences(LAST_MISSED_ID, -1) 1368779efd5Sopenharmony_ci } 1378779efd5Sopenharmony_ci 1388779efd5Sopenharmony_ci private setLastNotificationId(id: number, lastId?: number): boolean { 1398779efd5Sopenharmony_ci if (!lastId || this.lastMissedId < id) { 1408779efd5Sopenharmony_ci HiLog.i(TAG, `setLastNotificationId: ${id}`); 1418779efd5Sopenharmony_ci this.lastMissedId = id; 1428779efd5Sopenharmony_ci this.unRegisterDataChangeObserver(); 1438779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(LAST_MISSED_ID, id) 1448779efd5Sopenharmony_ci return true; 1458779efd5Sopenharmony_ci } 1468779efd5Sopenharmony_ci return false; 1478779efd5Sopenharmony_ci } 1488779efd5Sopenharmony_ci 1498779efd5Sopenharmony_ci private sendMissedCallNotify(lastId?: number) { 1508779efd5Sopenharmony_ci CallLogRepository.getInstance().findMissedCallLogUnread((data: CallLog[]) => { 1518779efd5Sopenharmony_ci HiLog.i(TAG, 'sendMissedCallNotify, callLog unread count:' + data.length); 1528779efd5Sopenharmony_ci if (data.length <= 0 || !this.setLastNotificationId(data[0].id, lastId)) { 1538779efd5Sopenharmony_ci HiLog.i(TAG, 'sendMissedCallNotify, No new CallLog.'); 1548779efd5Sopenharmony_ci return; 1558779efd5Sopenharmony_ci } 1568779efd5Sopenharmony_ci let phoneNums = new Set(); 1578779efd5Sopenharmony_ci for (let callLog of data) { 1588779efd5Sopenharmony_ci phoneNums.add(callLog.phoneNumber); 1598779efd5Sopenharmony_ci } 1608779efd5Sopenharmony_ci this.queryContactsName(Array.from(phoneNums), (numberMap) => { 1618779efd5Sopenharmony_ci let missedData: Map<string, MissedCallNotifyData> = new Map(); 1628779efd5Sopenharmony_ci for (let callLog of data) { 1638779efd5Sopenharmony_ci let displayName = callLog.phoneNumber; 1648779efd5Sopenharmony_ci if (numberMap.has(callLog.phoneNumber)) { 1658779efd5Sopenharmony_ci displayName = numberMap.get(callLog.phoneNumber); 1668779efd5Sopenharmony_ci } 1678779efd5Sopenharmony_ci if (!missedData.has(displayName)) { 1688779efd5Sopenharmony_ci missedData.set(displayName, { 1698779efd5Sopenharmony_ci phoneNumber: callLog.phoneNumber, 1708779efd5Sopenharmony_ci displayName: displayName, 1718779efd5Sopenharmony_ci id: callLog.id, 1728779efd5Sopenharmony_ci createTime: callLog.createTime, 1738779efd5Sopenharmony_ci count: 1, 1748779efd5Sopenharmony_ci ringDuration: callLog.ringDuration 1758779efd5Sopenharmony_ci }); 1768779efd5Sopenharmony_ci } else { 1778779efd5Sopenharmony_ci missedData.get(displayName).count++; 1788779efd5Sopenharmony_ci } 1798779efd5Sopenharmony_ci } 1808779efd5Sopenharmony_ci MissedCallNotifier.getInstance().updateMissedCallNotifications(missedData); 1818779efd5Sopenharmony_ci }) 1828779efd5Sopenharmony_ci }, lastId); 1838779efd5Sopenharmony_ci } 1848779efd5Sopenharmony_ci 1858779efd5Sopenharmony_ci private queryContactsName(numberList, callback) { 1868779efd5Sopenharmony_ci if (numberList.length == 0) { 1878779efd5Sopenharmony_ci HiLog.w(TAG, 'queryContactsName, has no number'); 1888779efd5Sopenharmony_ci callback(new Map()); 1898779efd5Sopenharmony_ci return; 1908779efd5Sopenharmony_ci } 1918779efd5Sopenharmony_ci ContactRepository.getInstance().queryContactDataByNumber(numberList, contacts => { 1928779efd5Sopenharmony_ci // Convert the result to Map, key: mobile number, value: name 1938779efd5Sopenharmony_ci let numberMap = this.getNumberMap(contacts); 1948779efd5Sopenharmony_ci callback(numberMap); 1958779efd5Sopenharmony_ci }); 1968779efd5Sopenharmony_ci } 1978779efd5Sopenharmony_ci 1988779efd5Sopenharmony_ci private getNumberMap(contacts) { 1998779efd5Sopenharmony_ci let numberMap = new Map(); 2008779efd5Sopenharmony_ci for (let item of contacts) { 2018779efd5Sopenharmony_ci if (!StringUtil.isEmpty(item.displayName)) { 2028779efd5Sopenharmony_ci numberMap.set(item.detailInfo, item.displayName); 2038779efd5Sopenharmony_ci } 2048779efd5Sopenharmony_ci } 2058779efd5Sopenharmony_ci return numberMap; 2068779efd5Sopenharmony_ci } 2078779efd5Sopenharmony_ci}