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_ciimport Notification from '@ohos.notificationManager' 168779efd5Sopenharmony_ciimport WantAgent from '@ohos.app.ability.wantAgent'; 178779efd5Sopenharmony_ciimport { HiLog, sharedPreferencesUtils } from '../../../../../../common'; 188779efd5Sopenharmony_ciimport notificationSubscribe from '@ohos.notificationSubscribe'; 198779efd5Sopenharmony_ciimport call from '@ohos.telephony.call'; 208779efd5Sopenharmony_ciimport { NotificationSubscriber } from 'notification/notificationSubscriber'; 218779efd5Sopenharmony_ci 228779efd5Sopenharmony_ciconst TAG = 'MissedCallNotifier'; 238779efd5Sopenharmony_ci 248779efd5Sopenharmony_ciconst BUNDLE_NAME: string = 'com.ohos.contacts'; 258779efd5Sopenharmony_ciconst ABILITY_NAME: string = 'com.ohos.contacts.MainAbility'; 268779efd5Sopenharmony_ciconst GROUP_NAME: string = 'MissedCall' 278779efd5Sopenharmony_ciconst KEY_MISSED_BADGE_NUM = 'missed_badge_number' 288779efd5Sopenharmony_ciconst KEY_ID = 'unread_call_notification_id' 298779efd5Sopenharmony_ciconst KEY_DISPLAY_NAME = 'unread_call_notification_displayName' 308779efd5Sopenharmony_ciconst KEY_COUNT = 'unread_call_notification_count' 318779efd5Sopenharmony_ciconst KEY_CREATE_TIME = 'unread_call_notification_create_time' 328779efd5Sopenharmony_ciconst KEY_RING_DURATION = 'unread_call_notification_ring_duration' 338779efd5Sopenharmony_ciconst actionBtnMaps = 348779efd5Sopenharmony_ci { 358779efd5Sopenharmony_ci 'notification.event.dialBack': $r('app.string.dial_back'), 368779efd5Sopenharmony_ci 'notification.event.message': $r('app.string.message'), 378779efd5Sopenharmony_ci }; 388779efd5Sopenharmony_ci 398779efd5Sopenharmony_ciexport class MissedCallNotifyData { 408779efd5Sopenharmony_ci id?: number; 418779efd5Sopenharmony_ci displayName?: string; 428779efd5Sopenharmony_ci readonly phoneNumber: string; 438779efd5Sopenharmony_ci count?: number; 448779efd5Sopenharmony_ci createTime?: number; 458779efd5Sopenharmony_ci ringDuration?: number; 468779efd5Sopenharmony_ci} 478779efd5Sopenharmony_ci 488779efd5Sopenharmony_ciexport class MissedCallNotifier { 498779efd5Sopenharmony_ci private label: string; 508779efd5Sopenharmony_ci private context: Context; 518779efd5Sopenharmony_ci private static sInstance: MissedCallNotifier = undefined; 528779efd5Sopenharmony_ci private missedBadgeNumber: number = -1; 538779efd5Sopenharmony_ci private UnReadMissedCallData: MissedCallNotifyData; 548779efd5Sopenharmony_ci 558779efd5Sopenharmony_ci /** 568779efd5Sopenharmony_ci * getInstance for MissedCallNotifier 578779efd5Sopenharmony_ci */ 588779efd5Sopenharmony_ci public static getInstance() { 598779efd5Sopenharmony_ci if (!MissedCallNotifier.sInstance || MissedCallNotifier.sInstance == undefined) { 608779efd5Sopenharmony_ci MissedCallNotifier.sInstance = new MissedCallNotifier(); 618779efd5Sopenharmony_ci } 628779efd5Sopenharmony_ci return MissedCallNotifier.sInstance; 638779efd5Sopenharmony_ci } 648779efd5Sopenharmony_ci 658779efd5Sopenharmony_ci /** 668779efd5Sopenharmony_ci * init 678779efd5Sopenharmony_ci * 688779efd5Sopenharmony_ci * @param ctx context needed init 698779efd5Sopenharmony_ci */ 708779efd5Sopenharmony_ci public init(ctx: Context) { 718779efd5Sopenharmony_ci this.context = ctx; 728779efd5Sopenharmony_ci if (!this.label) { 738779efd5Sopenharmony_ci this.label = this.getContext()?.resourceManager.getStringSync($r('app.string.missed_call')); 748779efd5Sopenharmony_ci } 758779efd5Sopenharmony_ci sharedPreferencesUtils.init(this.getContext()); 768779efd5Sopenharmony_ci } 778779efd5Sopenharmony_ci 788779efd5Sopenharmony_ci /** 798779efd5Sopenharmony_ci * update Missed Call Notification 808779efd5Sopenharmony_ci * 818779efd5Sopenharmony_ci * @param missedData missedCallData - missed call data for notification 828779efd5Sopenharmony_ci */ 838779efd5Sopenharmony_ci public async updateMissedCallNotifications(missedData: Map<string, MissedCallNotifyData>) { 848779efd5Sopenharmony_ci let notifyData = await this.getMissedCallNotifyDatas(); 858779efd5Sopenharmony_ci HiLog.i(TAG, `updateMissedCallNotifications notifyData:${notifyData.length} missedData: ${missedData.size}`) 868779efd5Sopenharmony_ci let badgeNumber: number = 0; 878779efd5Sopenharmony_ci if (notifyData.length > 0) { 888779efd5Sopenharmony_ci for (let notify of notifyData) { 898779efd5Sopenharmony_ci let key: string = notify.displayName; 908779efd5Sopenharmony_ci if (missedData.has(key)) { 918779efd5Sopenharmony_ci let missed = missedData.get(key) 928779efd5Sopenharmony_ci missedData.delete(key) 938779efd5Sopenharmony_ci if (missed.id != notify.id) { 948779efd5Sopenharmony_ci notify.createTime = missed.createTime; 958779efd5Sopenharmony_ci notify.ringDuration = missed.ringDuration; 968779efd5Sopenharmony_ci notify.count += missed.count; 978779efd5Sopenharmony_ci this.sendNotification(notify); 988779efd5Sopenharmony_ci } 998779efd5Sopenharmony_ci } 1008779efd5Sopenharmony_ci badgeNumber += notify.count; 1018779efd5Sopenharmony_ci } 1028779efd5Sopenharmony_ci } 1038779efd5Sopenharmony_ci for (let notify of missedData.values()) { 1048779efd5Sopenharmony_ci await this.sendNotification(notify); 1058779efd5Sopenharmony_ci badgeNumber += notify.count; 1068779efd5Sopenharmony_ci } 1078779efd5Sopenharmony_ci if (badgeNumber > 0) { 1088779efd5Sopenharmony_ci this.setMissedBadgeNumber(badgeNumber); 1098779efd5Sopenharmony_ci } 1108779efd5Sopenharmony_ci } 1118779efd5Sopenharmony_ci 1128779efd5Sopenharmony_ci /** 1138779efd5Sopenharmony_ci * cancel Missed Call Notification 1148779efd5Sopenharmony_ci */ 1158779efd5Sopenharmony_ci public cancelAllNotification() { 1168779efd5Sopenharmony_ci HiLog.i(TAG, 'cancelNotification,cancel all') 1178779efd5Sopenharmony_ci this.setMissedBadgeNumber(0); 1188779efd5Sopenharmony_ci Notification.cancelGroup(GROUP_NAME).catch(error => { 1198779efd5Sopenharmony_ci HiLog.e(TAG, `cancelNotification,err ${JSON.stringify(error)}}`) 1208779efd5Sopenharmony_ci }); 1218779efd5Sopenharmony_ci } 1228779efd5Sopenharmony_ci 1238779efd5Sopenharmony_ci /** 1248779efd5Sopenharmony_ci * get Missed Call BadgeNumber 1258779efd5Sopenharmony_ci */ 1268779efd5Sopenharmony_ci public async getMissedBadgeNumber() { 1278779efd5Sopenharmony_ci if (this.missedBadgeNumber == -1) { 1288779efd5Sopenharmony_ci this.missedBadgeNumber = <number> await sharedPreferencesUtils.getFromPreferences(KEY_MISSED_BADGE_NUM, -1); 1298779efd5Sopenharmony_ci } 1308779efd5Sopenharmony_ci return this.missedBadgeNumber; 1318779efd5Sopenharmony_ci } 1328779efd5Sopenharmony_ci 1338779efd5Sopenharmony_ci /** 1348779efd5Sopenharmony_ci * cancel Missed Call Notification By NotificationId 1358779efd5Sopenharmony_ci * 1368779efd5Sopenharmony_ci * @param id Notification Id 1378779efd5Sopenharmony_ci */ 1388779efd5Sopenharmony_ci public async cancelNotificationById(id: number, count: number) { 1398779efd5Sopenharmony_ci HiLog.i(TAG, 'cancelNotificationById:' + id) 1408779efd5Sopenharmony_ci Notification.cancel(id, this.label).catch(error => { 1418779efd5Sopenharmony_ci HiLog.e(TAG, `cancelNotificationById,err ${JSON.stringify(error)}}`) 1428779efd5Sopenharmony_ci }); 1438779efd5Sopenharmony_ci let badgeNumber = await this.getMissedBadgeNumber(); 1448779efd5Sopenharmony_ci badgeNumber -= count; 1458779efd5Sopenharmony_ci if (badgeNumber >= 0) { 1468779efd5Sopenharmony_ci this.setMissedBadgeNumber(badgeNumber); 1478779efd5Sopenharmony_ci } 1488779efd5Sopenharmony_ci } 1498779efd5Sopenharmony_ci 1508779efd5Sopenharmony_ci private constructor() { 1518779efd5Sopenharmony_ci } 1528779efd5Sopenharmony_ci 1538779efd5Sopenharmony_ci private getContext() { 1548779efd5Sopenharmony_ci if (this.context && this.context != undefined) { 1558779efd5Sopenharmony_ci return this.context; 1568779efd5Sopenharmony_ci } 1578779efd5Sopenharmony_ci return globalThis.context; 1588779efd5Sopenharmony_ci } 1598779efd5Sopenharmony_ci 1608779efd5Sopenharmony_ci private async getMissedCallNotifyDatas() { 1618779efd5Sopenharmony_ci HiLog.i(TAG, `getMissedCallNotifyDatas in`) 1628779efd5Sopenharmony_ci let result: Array<MissedCallNotifyData> = []; 1638779efd5Sopenharmony_ci const notifications: Array<Notification.NotificationRequest> = 1648779efd5Sopenharmony_ci await Notification.getAllActiveNotifications() 1658779efd5Sopenharmony_ci for (let notify of notifications) { 1668779efd5Sopenharmony_ci if (notify.groupName == GROUP_NAME && notify.extraInfo) { 1678779efd5Sopenharmony_ci result.push(<MissedCallNotifyData> notify.extraInfo); 1688779efd5Sopenharmony_ci } 1698779efd5Sopenharmony_ci } 1708779efd5Sopenharmony_ci HiLog.i(TAG, `getMissedCallNotifyDatas result: ${result.length}`) 1718779efd5Sopenharmony_ci return result; 1728779efd5Sopenharmony_ci } 1738779efd5Sopenharmony_ci 1748779efd5Sopenharmony_ci private async sendNotification(missedCallData: MissedCallNotifyData) { 1758779efd5Sopenharmony_ci const {id, displayName, count, createTime, ringDuration} = missedCallData; 1768779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_ID, id); 1778779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_DISPLAY_NAME, displayName); 1788779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_COUNT, count); 1798779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_CREATE_TIME, createTime); 1808779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_RING_DURATION, ringDuration) 1818779efd5Sopenharmony_ci HiLog.i(TAG, `sendNotification in id:${id}, count:${count}, createTime:${createTime}`) 1828779efd5Sopenharmony_ci let str_text = this.getContext()?.resourceManager.getStringSync($r('app.string.contacts_ring_times')) + 1838779efd5Sopenharmony_ci ringDuration + this.getContext()?.resourceManager.getStringSync($r('app.string.contacts_time_sec')); 1848779efd5Sopenharmony_ci if (ringDuration === 0) { 1858779efd5Sopenharmony_ci str_text = $r('app.string.missed_call') 1868779efd5Sopenharmony_ci } 1878779efd5Sopenharmony_ci const notificationRequest: Notification.NotificationRequest = { 1888779efd5Sopenharmony_ci content: { 1898779efd5Sopenharmony_ci contentType: Notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, 1908779efd5Sopenharmony_ci normal: { 1918779efd5Sopenharmony_ci title: count > 1 ? `${displayName} (${count})` : displayName, 1928779efd5Sopenharmony_ci text: str_text, 1938779efd5Sopenharmony_ci additionalText: missedCallData.phoneNumber 1948779efd5Sopenharmony_ci }, 1958779efd5Sopenharmony_ci }, 1968779efd5Sopenharmony_ci id: id, 1978779efd5Sopenharmony_ci label: this.label, 1988779efd5Sopenharmony_ci groupName: GROUP_NAME, 1998779efd5Sopenharmony_ci slotType: Notification.SlotType.SOCIAL_COMMUNICATION, 2008779efd5Sopenharmony_ci deliveryTime: new Date().getTime(), 2018779efd5Sopenharmony_ci extraInfo: missedCallData 2028779efd5Sopenharmony_ci } 2038779efd5Sopenharmony_ci 2048779efd5Sopenharmony_ci let wantAgentObj = await this.getWantAgent(missedCallData, 'notification.event.click'); 2058779efd5Sopenharmony_ci notificationRequest.wantAgent = wantAgentObj; 2068779efd5Sopenharmony_ci notificationRequest.actionButtons = []; 2078779efd5Sopenharmony_ci for (const key of Object.keys(actionBtnMaps)) { 2088779efd5Sopenharmony_ci const wantAgent = await this.getWantAgent(missedCallData, key); 2098779efd5Sopenharmony_ci const title = this.getContext()?.resourceManager.getStringSync(actionBtnMaps[key]); 2108779efd5Sopenharmony_ci notificationRequest.actionButtons.push({ 2118779efd5Sopenharmony_ci title: title, 2128779efd5Sopenharmony_ci wantAgent: wantAgent 2138779efd5Sopenharmony_ci }); 2148779efd5Sopenharmony_ci } 2158779efd5Sopenharmony_ci notificationRequest.removalWantAgent = await this.createWantAgentForCommonEvent(missedCallData, 'notification.event.cancel'); 2168779efd5Sopenharmony_ci Notification.publish(notificationRequest).then(() => { 2178779efd5Sopenharmony_ci HiLog.i(TAG, '===>publish promise success req.id : ' + notificationRequest.id); 2188779efd5Sopenharmony_ci }).catch((err) => { 2198779efd5Sopenharmony_ci HiLog.e(TAG, '===>publish promise failed because ' + JSON.stringify(err)); 2208779efd5Sopenharmony_ci }); 2218779efd5Sopenharmony_ci HiLog.i(TAG, 'sendNotification end') 2228779efd5Sopenharmony_ci } 2238779efd5Sopenharmony_ci 2248779efd5Sopenharmony_ci /** 2258779efd5Sopenharmony_ci * send Unread Call Notification 2268779efd5Sopenharmony_ci */ 2278779efd5Sopenharmony_ci public async sendUnreadCallNotification(map: Map<string, string>) { 2288779efd5Sopenharmony_ci let id: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_ID, -1); 2298779efd5Sopenharmony_ci let displayName: string = <string> await sharedPreferencesUtils.getFromPreferences(KEY_DISPLAY_NAME, ''); 2308779efd5Sopenharmony_ci let count: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_COUNT, -1); 2318779efd5Sopenharmony_ci let createTime: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_CREATE_TIME, -1); 2328779efd5Sopenharmony_ci let ringDuration: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_RING_DURATION, -1); 2338779efd5Sopenharmony_ci let missCallData = map.get('missedPhoneJson') 2348779efd5Sopenharmony_ci const parameters = JSON.parse(JSON.stringify(missCallData)); 2358779efd5Sopenharmony_ci for (let i = 0; i < parameters.phoneNumberList.length; i++) { 2368779efd5Sopenharmony_ci const missedPhoneNumber = parameters.phoneNumberList[i] 2378779efd5Sopenharmony_ci const missedNum = parameters.countList[i] 2388779efd5Sopenharmony_ci if (i === (parameters.phoneNumberList.length -1)) { 2398779efd5Sopenharmony_ci this.UnReadMissedCallData = { 2408779efd5Sopenharmony_ci phoneNumber: missedPhoneNumber, 2418779efd5Sopenharmony_ci displayName: missedPhoneNumber, 2428779efd5Sopenharmony_ci id: i, 2438779efd5Sopenharmony_ci createTime: createTime, 2448779efd5Sopenharmony_ci count: count, 2458779efd5Sopenharmony_ci ringDuration: ringDuration 2468779efd5Sopenharmony_ci } 2478779efd5Sopenharmony_ci } else { 2488779efd5Sopenharmony_ci this.UnReadMissedCallData = { 2498779efd5Sopenharmony_ci phoneNumber: missedPhoneNumber, 2508779efd5Sopenharmony_ci displayName: missedPhoneNumber, 2518779efd5Sopenharmony_ci id: i, 2528779efd5Sopenharmony_ci createTime: createTime, 2538779efd5Sopenharmony_ci count: count, 2548779efd5Sopenharmony_ci ringDuration: 0 2558779efd5Sopenharmony_ci } 2568779efd5Sopenharmony_ci } 2578779efd5Sopenharmony_ci this.sendNotification(this.UnReadMissedCallData); 2588779efd5Sopenharmony_ci } 2598779efd5Sopenharmony_ci } 2608779efd5Sopenharmony_ci 2618779efd5Sopenharmony_ci private setMissedBadgeNumber(newBadgeNum: number) { 2628779efd5Sopenharmony_ci HiLog.i(TAG, 'setMissedBadgeNumber :' + newBadgeNum); 2638779efd5Sopenharmony_ci this.missedBadgeNumber = newBadgeNum; 2648779efd5Sopenharmony_ci Notification.setBadgeNumber(newBadgeNum); 2658779efd5Sopenharmony_ci sharedPreferencesUtils.saveToPreferences(KEY_MISSED_BADGE_NUM, newBadgeNum); 2668779efd5Sopenharmony_ci } 2678779efd5Sopenharmony_ci 2688779efd5Sopenharmony_ci /** 2698779efd5Sopenharmony_ci * create wantAgent for common event 2708779efd5Sopenharmony_ci * 2718779efd5Sopenharmony_ci * @param mAction 2728779efd5Sopenharmony_ci * @return return the created WantAgent object. 2738779efd5Sopenharmony_ci */ 2748779efd5Sopenharmony_ci private async createWantAgentForCommonEvent(missedCallData, action?: string) { 2758779efd5Sopenharmony_ci return await WantAgent.getWantAgent({ 2768779efd5Sopenharmony_ci wants: [{ action: 'contact.event.CANCEL_MISSED', parameters: { 2778779efd5Sopenharmony_ci action: action, 2788779efd5Sopenharmony_ci missedCallData: missedCallData 2798779efd5Sopenharmony_ci }, }], 2808779efd5Sopenharmony_ci operationType: WantAgent.OperationType.SEND_COMMON_EVENT, 2818779efd5Sopenharmony_ci requestCode: 0 2828779efd5Sopenharmony_ci }) 2838779efd5Sopenharmony_ci } 2848779efd5Sopenharmony_ci 2858779efd5Sopenharmony_ci private getWantAgent(missedCallData: MissedCallNotifyData, action: string) { 2868779efd5Sopenharmony_ci let data: any = {} 2878779efd5Sopenharmony_ci data.action = action, 2888779efd5Sopenharmony_ci data.missedCallData = missedCallData 2898779efd5Sopenharmony_ci if (action == 'notification.event.dialBack') { 2908779efd5Sopenharmony_ci HiLog.i(TAG, 'getWantAgent add page_flag_edit_before_calling') 2918779efd5Sopenharmony_ci return this.createWantAgentForCommonEvent(missedCallData, action); 2928779efd5Sopenharmony_ci } 2938779efd5Sopenharmony_ci return WantAgent.getWantAgent({ 2948779efd5Sopenharmony_ci wants: [{ 2958779efd5Sopenharmony_ci deviceId: '', 2968779efd5Sopenharmony_ci bundleName: BUNDLE_NAME, 2978779efd5Sopenharmony_ci abilityName: ABILITY_NAME, 2988779efd5Sopenharmony_ci uri: '', 2998779efd5Sopenharmony_ci type: 'phone', 3008779efd5Sopenharmony_ci parameters: data, 3018779efd5Sopenharmony_ci entities: [] 3028779efd5Sopenharmony_ci }], 3038779efd5Sopenharmony_ci requestCode: 0, 3048779efd5Sopenharmony_ci operationType: WantAgent.OperationType.START_ABILITY, 3058779efd5Sopenharmony_ci wantAgentFlags: [WantAgent.WantAgentFlags.ONE_TIME_FLAG] 3068779efd5Sopenharmony_ci }); 3078779efd5Sopenharmony_ci } 3088779efd5Sopenharmony_ci}