1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19/* 20 * 2021.01.08 - The function 'standardization' is simpler and more accurate. 21 * And extend function 'send' to fit framework. 22 * Copyright (c) 2021 Huawei Device Co., Ltd. 23 */ 24 25import { 26 Log, 27 typof 28} from '../../../utils/index'; 29import CallbackManager from './CallbackManager'; 30 31type OptionsType = Partial<Record<'action' | 'module' | 'method' | 'ref', string>> 32 33/** 34 * <p>Tasks processing center.</p> 35 * <p>Instructs the Native module to perform operations based on the message sent by the listener.</p> 36 * <p>Then the Native module invokes the callNative() callback function in sendTasks()<br> 37 * to send the message to the Native module.</p> 38 */ 39export class TaskCenter { 40 public instanceId: string; 41 public callbackManager: CallbackManager; 42 43 constructor(id: string) { 44 this.instanceId = id; 45 this.callbackManager = new CallbackManager(id); 46 } 47 48 /** 49 * Execute the consume() function from callbackManager class. 50 * @param {number} callbackId - Callback id. 51 * @param {Object} data - Data that needed. 52 * @param {boolean} ifKeepAlive - If keepAlive is false, delete this callback. 53 * @return {*} 54 */ 55 public consumeCallback(callbackId: number, data: object, ifKeepAlive: boolean): any | Error { 56 return this.callbackManager.consume(callbackId, data, ifKeepAlive); 57 } 58 59 /** 60 * Execute the close() function from callbackManager class. 61 * @param {number} callbackId - Callback id. 62 */ 63 public destroyCallback(): void { 64 return this.callbackManager.destroy(); 65 } 66 67 /** 68 * Execute the remove() function from callbackManager class. 69 * @param {number} callbackId - Callback id. 70 */ 71 public removeCallback(callbackId: number): void { 72 this.callbackManager.remove(callbackId); 73 } 74 75 /** 76 * Execute the isEmpty() function from callbackManager class. 77 * @param {number} callbackId - Callback id. 78 * @return {boolean} If callbacklist object is empty, return true. Otherwise return false. 79 */ 80 public callbackIsEmpty(): boolean { 81 return this.callbackManager.isEmpty(); 82 } 83 84 /** 85 * Standardizing a value. Specially, if the value is a function, generate a function id. 86 * @param {*} arg - Any type. 87 * @return {*} 88 */ 89 public standardization(arg: any): any { 90 const type = typof(arg); 91 if (type === 'object') { 92 const ans = {}; 93 Object.keys(arg).forEach(key => { 94 ans[key] = this.standardization(arg[key]); 95 }); 96 return ans; 97 } else if (type === 'function') { 98 return this.callbackManager.add(arg).toString(); 99 } else if (type === 'array') { 100 return arg.map(i => this.standardization(i)); 101 } else { 102 return arg; 103 } 104 } 105 106 /** 107 * Instruct the Native module to perform operations based on the message sent by the listener. 108 * @param {string} type - Such as dom, module and component. 109 * @param {OptionsType} options - Include action, module and method. 110 * @param {*} args - Args of a Vm. 111 */ 112 public send(type: string, options: OptionsType, args: any): any { 113 const { 114 action, 115 module, 116 method 117 } = options; 118 if (type !== 'dom') { 119 args = args.map(arg => this.standardization(arg)); 120 } 121 switch (type) { 122 case 'dom': 123 if (typeof ace !== 'undefined' && 124 typeof ace.domCreateBody !== 'undefined' && 125 typeof ace.domAddElement !== 'undefined') { 126 if (action === 'createBody') { 127 ace.domCreateBody( 128 0, 129 args[0].type, 130 args[0].attr, 131 args[0].style, 132 args[0].event 133 ); 134 } else if (action === 'addElement') { 135 ace.domAddElement( 136 args[0], 137 args[1].ref, 138 args[1].type, 139 args[1].attr, 140 args[1].style, 141 args[1].event, 142 args[1].customComponent, 143 args[2], 144 this.instanceId 145 ); 146 } else if (action === 'updateAttrs') { 147 ace.updateElementAttrs( 148 args[0], 149 args[1], 150 this.instanceId 151 ); 152 } else if (action === 'updateStyle') { 153 ace.updateElementStyles( 154 args[0], 155 args[1], 156 this.instanceId 157 ); 158 } else if (action === 'createFinish') { 159 ace.onCreateFinish(); 160 return; 161 } else if (action === 'updateFinish') { 162 ace.onUpdateFinish(); 163 return; 164 } else if (action === 'removeElement') { 165 ace.removeElement( 166 args[0], 167 this.instanceId 168 ); 169 } else { 170 Log.error( 171 'TaskCenter.js: send() unsupported action. IGNORING!' 172 ); 173 } 174 return; 175 } else { 176 Log.error( 177 'TaskCenter.js: attempting acev1 method for calling native' 178 ); 179 return; 180 } 181 182 case 'module': 183 switch (module) { 184 case 'system.fetch': 185 if (method === 'fetch') { 186 Log.error( 187 'TaskCenter.js: send: module system.fetch. calling ace.fetch.' 188 ); 189 ace.onFetchRequest(args[1], JSON.stringify(args)); 190 return; 191 } else { 192 Log.error( 193 'TaskCenter.js: send: module system.fetch. unrecognized method. Ignoring.' 194 ); 195 } 196 break; 197 case 'system.device': 198 return ace.callNative(JSON.stringify(options), args[args.length - 1]); 199 case 'system.router': 200 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 201 case 'system.prompt': 202 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 203 case 'system.app': 204 return ace.callNative(JSON.stringify(options), args); 205 case 'system.configuration': 206 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 207 case 'system.grid': 208 return ace.callNative(JSON.stringify(options), args); 209 case 'internal.jsResult': 210 return ace.callNative(JSON.stringify(options), args); 211 case 'timer': 212 return ace.callNative(JSON.stringify(options), args); 213 case 'system.offscreenCanvas': 214 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 215 case 'system.image': 216 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 217 case 'system.mediaquery': 218 return ace.callNative(JSON.stringify(options), args); 219 case 'animation': 220 return ace.callNative(JSON.stringify(options), args[0]); 221 case 'system.resource': 222 return ace.callNative(JSON.stringify(options), args); 223 case 'ohos.animator': 224 return ace.callNative(JSON.stringify(options), JSON.stringify(args[0])); 225 default: 226 break; 227 } 228 break; 229 230 case 'component': 231 return ace.callComponent(options.ref, method, JSON.stringify(args)); 232 default: 233 break; 234 } 235 } 236} 237