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") 16var accessControl = requireNapi("abilityAccessCtrl") 17 18const EVENT_CALL_NOTIFY = 1; 19const REQUEST_SUCCESS = 0; 20const REQUEST_FAILED = 1; 21const PERMISSION_ABILITY_BACKGROUND_COMMUNICATION = "ohos.permission.ABILITY_BACKGROUND_COMMUNICATION" 22 23const ERROR_CODE_INVALID_PARAM = 401; 24const ERROR_CODE_FUNC_REGISTERED = 16200004; 25const ERROR_CODE_FUNC_NOT_EXIST = 16200005; 26const ERROR_CODE_INNER_ERROR = 16000050; 27 28const ERROR_MSG_INVALID_PARAM = "Invalid input parameter."; 29const ERROR_MSG_FUNC_REGISTERED = "Method registered. The method has registered."; 30const ERROR_MSG_FUNC_NOT_EXIST = "Method not registered. The method has not registered."; 31const ERROR_MSG_INNER_ERROR = "Inner Error."; 32 33var errMap = new Map(); 34errMap.set(ERROR_CODE_INVALID_PARAM, ERROR_MSG_INVALID_PARAM); 35errMap.set(ERROR_CODE_FUNC_REGISTERED, ERROR_MSG_FUNC_REGISTERED); 36errMap.set(ERROR_CODE_FUNC_NOT_EXIST, ERROR_MSG_FUNC_NOT_EXIST); 37errMap.set(ERROR_CODE_INNER_ERROR, ERROR_MSG_INNER_ERROR); 38 39class BusinessError extends Error { 40 constructor(code) { 41 let msg = ""; 42 if (errMap.has(code)) { 43 msg = errMap.get(code); 44 } else { 45 msg = ERROR_MSG_INNER_ERROR; 46 } 47 super(msg); 48 this.code = code; 49 } 50} 51 52class Callee extends rpc.RemoteObject { 53 constructor(des) { 54 if (typeof des === 'string') { 55 super(des); 56 this.callList = new Map(); 57 this.startUpNewRule = false; 58 console.log("Callee constructor is OK " + typeof des); 59 } else { 60 console.log("Callee constructor error, des is " + typeof des); 61 return null; 62 } 63 } 64 65 setNewRuleFlag(flag) { 66 this.startUpNewRule = flag; 67 } 68 69 onRemoteMessageRequest(code, data, reply, option) { 70 console.log("Callee onRemoteMessageRequest code [" + typeof code + " " + code + "]"); 71 if (this.startUpNewRule && rpc.IPCSkeleton.isLocalCalling()) { 72 console.log("Use new start up rule, check caller permission."); 73 let accessManger = accessControl.createAtManager(); 74 let accessTokenId = rpc.IPCSkeleton.getCallingTokenId(); 75 let grantStatus = 76 accessManger.verifyAccessTokenSync(accessTokenId, PERMISSION_ABILITY_BACKGROUND_COMMUNICATION); 77 if (grantStatus === accessControl.GrantStatus.PERMISSION_DENIED) { 78 console.log( 79 "Callee onRemoteMessageRequest error, the Caller does not have PERMISSION_ABILITY_BACKGROUND_COMMUNICATION"); 80 return false; 81 } 82 } 83 84 if (typeof code !== 'number' || typeof data !== 'object' || 85 typeof reply !== 'object' || typeof option !== 'object') { 86 console.log("Callee onRemoteMessageRequest error, code is [" + 87 typeof code + "], data is [" + typeof data + "], reply is [" + 88 typeof reply + "], option is [" + typeof option + "]"); 89 return false; 90 } 91 92 console.log("Callee onRemoteMessageRequest code proc"); 93 if (code == EVENT_CALL_NOTIFY) { 94 if (this.callList == null) { 95 console.log("Callee onRemoteMessageRequest error, this.callList is nullptr"); 96 return false; 97 } 98 99 let method = data.readString(); 100 console.log("Callee onRemoteMessageRequest method [" + method + "]"); 101 let func = this.callList.get(method); 102 if (typeof func !== 'function') { 103 console.log("Callee onRemoteMessageRequest error, get func is " + typeof func); 104 return false; 105 } 106 107 let result = func(data); 108 if (typeof result === 'object' && result != null) { 109 reply.writeInt(REQUEST_SUCCESS); 110 reply.writeString(typeof result); 111 reply.writeParcelable(result); 112 console.log("Callee onRemoteMessageRequest code proc Packed data"); 113 } else { 114 reply.writeInt(REQUEST_FAILED); 115 reply.writeString(typeof result); 116 console.log("Callee onRemoteMessageRequest error, retval is " + REQUEST_FAILED + ", type is " + typeof result); 117 } 118 } else { 119 console.log("Callee onRemoteMessageRequest error, code is " + code); 120 return false; 121 } 122 console.log("Callee onRemoteMessageRequest code proc success"); 123 return true; 124 } 125 126 on(method, callback) { 127 if (typeof method !== 'string' || method == "" || typeof callback !== 'function') { 128 console.log( 129 "Callee on error, method is [" + typeof method + "], typeof callback [" + typeof callback + "]"); 130 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 131 } 132 133 if (this.callList == null) { 134 console.log("Callee on error, this.callList is nullptr"); 135 throw new BusinessError(ERROR_CODE_INNER_ERROR);; 136 } 137 138 if (this.callList.has(method)) { 139 console.log("Callee on error, [" + method + "] has registered"); 140 throw new BusinessError(ERROR_CODE_FUNC_REGISTERED); 141 } 142 143 this.callList.set(method, callback); 144 console.log("Callee on method [" + method + "]"); 145 } 146 147 off(method) { 148 if (typeof method !== 'string' || method == "") { 149 console.log("Callee off error, method is [" + typeof method + "]"); 150 throw new BusinessError(ERROR_CODE_INVALID_PARAM); 151 } 152 153 if (this.callList == null) { 154 console.log("Callee off error, this.callList is null"); 155 throw new BusinessError(ERROR_CODE_INNER_ERROR); 156 } 157 158 if (!this.callList.has(method)) { 159 console.log("Callee off error, this.callList not found " + method); 160 throw new BusinessError(ERROR_CODE_FUNC_NOT_EXIST); 161 } 162 163 this.callList.delete(method); 164 console.log("Callee off method [" + method + "]"); 165 } 166} 167 168export default Callee 169