1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15var rpc = requireNapi("rpc") 16 17const EVENT_CALL_NOTIFY = 1; 18const REQUEST_SUCCESS = 0; 19 20const ERROR_CODE_INVALID_PARAM = 401; 21const ERROR_CODE_CALLER_RELEASED = 16200001; 22const ERROR_CODE_CLAAEE_INVALID = 16200002; 23const ERROR_CODE_INNER_ERROR = 16000050; 24 25const ERROR_MSG_INVALID_PARAM = "Invalid input parameter."; 26const ERROR_MSG_CALLER_RELEASED = "Caller released. The caller has been released."; 27const ERROR_MSG_CLAAEE_INVALID = "Callee invalid. The callee does not exist."; 28const ERROR_MSG_INNER_ERROR = "Inner Error."; 29 30var errMap = new Map(); 31errMap.set(ERROR_CODE_INVALID_PARAM, ERROR_MSG_INVALID_PARAM); 32errMap.set(ERROR_CODE_CALLER_RELEASED, ERROR_MSG_CALLER_RELEASED); 33errMap.set(ERROR_CODE_CLAAEE_INVALID, ERROR_MSG_CLAAEE_INVALID); 34errMap.set(ERROR_CODE_INNER_ERROR, ERROR_MSG_INNER_ERROR); 35 36class BusinessError extends Error { 37 constructor(code) { 38 let msg = ""; 39 if (errMap.has(code)) { 40 msg = errMap.get(code); 41 } else { 42 msg = ERROR_MSG_INNER_ERROR; 43 } 44 super(msg); 45 this.code = code; 46 } 47} 48 49class Caller { 50 constructor(obj) { 51 console.log("Caller::constructor obj is " + typeof obj); 52 this.__call_obj__ = obj; 53 this.releaseState = false; 54 } 55 56 call(method, data) { 57 return new Promise(async (resolve, reject) => { 58 console.log("Caller call method [" + method + "]"); 59 if (typeof method !== 'string' || typeof data !== 'object') { 60 console.log("Caller call " + typeof method + " " + typeof data); 61 reject(new BusinessError(ERROR_CODE_INVALID_PARAM)); 62 return; 63 } 64 65 if (method == '' || data == null) { 66 console.log("Caller call " + method + ", " + data); 67 reject(new BusinessError(ERROR_CODE_INVALID_PARAM)); 68 return; 69 } 70 71 if (this.releaseState == true) { 72 console.log("Caller call this.callee release"); 73 reject(new BusinessError(ERROR_CODE_CALLER_RELEASED)); 74 return; 75 } 76 77 if (this.__call_obj__.callee == null) { 78 console.log("Caller call this.callee is nullptr"); 79 reject(new BusinessError(ERROR_CODE_CLAAEE_INVALID)); 80 return; 81 } 82 83 console.log("Caller call msgData rpc.MessageSequence create"); 84 let msgData = rpc.MessageSequence.create(); 85 msgData.writeString(method); 86 let msgReply = rpc.MessageSequence.create(); 87 let option = rpc.MessageOption(); 88 msgData.writeParcelable(data); 89 90 let retData = undefined; 91 try { 92 retData = await this.__call_obj__.callee.sendMessageRequest(EVENT_CALL_NOTIFY, msgData, msgReply, option); 93 console.log("Caller call msgData rpc.sendMessageRequest called"); 94 if (retData.errCode != 0) { 95 msgData.reclaim(); 96 msgReply.reclaim(); 97 console.log("Caller call return errCode " + retData.errCode); 98 reject(new BusinessError(retData.errCode)); 99 return; 100 } 101 } catch (e) { 102 console.log("Caller call msgData rpc.sendMessageRequest error " + e); 103 } 104 105 try { 106 let retval = retData.reply.readInt(); 107 let str = retData.reply.readString(); 108 if (retval === REQUEST_SUCCESS && str === 'object') { 109 console.log("Caller call return str " + str); 110 msgData.reclaim(); 111 msgReply.reclaim(); 112 } else { 113 console.log("Caller call retval is [" + retval + "], str [" + str + "]"); 114 msgData.reclaim(); 115 msgReply.reclaim(); 116 reject(new BusinessError(retval)); 117 return; 118 } 119 } catch (e) { 120 console.log("Caller call msgData sendMessageRequest retval error"); 121 reject(new BusinessError(ERROR_CODE_INNER_ERROR)); 122 return; 123 } 124 125 console.log("Caller call msgData sendMessageRequest end"); 126 resolve(undefined); 127 return; 128 }); 129 } 130 131 callWithResult(method, data) { 132 return new Promise(async (resolve, reject) => { 133 console.log("Caller callWithResult method [" + method + "]"); 134 if (typeof method !== 'string' || typeof data !== 'object') { 135 console.log("Caller callWithResult " + typeof method + " " + typeof data); 136 reject(new BusinessError(ERROR_CODE_INVALID_PARAM)); 137 return; 138 } 139 140 if (method == '' || data == null) { 141 console.log("Caller callWithResult " + method + ", " + data); 142 reject(new BusinessError(ERROR_CODE_INVALID_PARAM)); 143 return; 144 } 145 146 if (this.releaseState == true) { 147 console.log("Caller callWithResult this.callee release"); 148 reject(new BusinessError(ERROR_CODE_CALLER_RELEASED)); 149 return; 150 } 151 152 if (this.__call_obj__.callee == null) { 153 console.log("Caller callWithResult this.callee is nullptr"); 154 reject(new BusinessError(ERROR_CODE_CLAAEE_INVALID)); 155 return; 156 } 157 158 console.log("Caller callWithResult msgData rpc.MessageSequence create"); 159 let msgData = rpc.MessageSequence.create(); 160 msgData.writeString(method); 161 let msgReply = rpc.MessageSequence.create(); 162 let option = rpc.MessageOption(); 163 msgData.writeParcelable(data); 164 165 let reply = undefined; 166 let retData = undefined; 167 try { 168 retData = await this.__call_obj__.callee.sendMessageRequest(EVENT_CALL_NOTIFY, msgData, msgReply, option); 169 console.log("Caller callWithResult msgData rpc.sendMessageRequest called"); 170 if (retData.errCode != 0) { 171 msgData.reclaim(); 172 msgReply.reclaim(); 173 console.log("Caller callWithResult return errCode " + retData.errCode); 174 reject(new BusinessError(retData.errCode)); 175 return; 176 } 177 } catch (e) { 178 console.log("Caller call msgData rpc.MessageSequence error " + e); 179 } 180 181 try { 182 let retval = retData.reply.readInt(); 183 let str = retData.reply.readString(); 184 if (retval === REQUEST_SUCCESS && str === 'object') { 185 console.log("Caller callWithResult return str " + str); 186 msgData.reclaim(); 187 reply = retData.reply; 188 } else { 189 console.log("Caller callWithResult retval is [" + retval + "], str [" + str + "]"); 190 msgData.reclaim(); 191 msgReply.reclaim(); 192 reject(new BusinessError(retval)); 193 return; 194 } 195 } catch (e) { 196 console.log("Caller callWithResult msgData sendMessageRequest retval error"); 197 reject(new BusinessError(ERROR_CODE_INNER_ERROR)); 198 return; 199 } 200 201 console.log("Caller callWithResult msgData sendMessageRequest end"); 202 resolve(reply); 203 return; 204 }); 205 } 206 207 release() { 208 console.log("Caller release js called."); 209 if (this.releaseState == true) { 210 console.log("Caller release remoteObj releaseState is true"); 211 throw new BusinessError(ERROR_CODE_CALLER_RELEASED); 212 } 213 214 if (this.__call_obj__.callee == null) { 215 console.log("Caller release call remoteObj is released"); 216 throw new BusinessError(ERROR_CODE_CLAAEE_INVALID); 217 } 218 219 this.releaseState = true; 220 this.__call_obj__.release(); 221 } 222 223 onRelease(callback) { 224 console.log("Caller onRelease jscallback called."); 225 if (typeof callback !== 'function') { 226 console.log("Caller onRelease " + typeof callback); 227 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 228 } 229 230 if (this.releaseState == true) { 231 console.log("Caller onRelease remoteObj releaseState is true"); 232 throw new BusinessError(ERROR_CODE_CALLER_RELEASED); 233 } 234 235 this.__call_obj__.onRelease(callback); 236 } 237 238 on(type, callback) { 239 console.log("Caller onRelease jscallback called."); 240 if (typeof type !== 'string' || type !== "release") { 241 console.log( 242 "Caller onRelease error, input [type] is invalid."); 243 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 244 } 245 246 if (typeof callback !== 'function') { 247 console.log("Caller onRelease error " + typeof callback); 248 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 249 } 250 251 if (this.releaseState == true) { 252 console.log("Caller onRelease error, remoteObj releaseState is true"); 253 throw new BusinessError(ERROR_CODE_CALLER_RELEASED); 254 } 255 256 this.__call_obj__.onRelease(callback); 257 } 258 259 off(type, callback) { 260 if (typeof type !== 'string' || type !== "release") { 261 console.log( 262 "Caller onRelease error, input [type] is invalid."); 263 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 264 } 265 266 if (callback && typeof callback !== 'function') { 267 console.log("Caller onRelease error " + typeof callback); 268 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 269 } 270 // Empty 271 } 272} 273 274export default Caller 275