• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 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 */
15let 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
30let 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      const checkError = this.callCheck(method, data);
59      if (checkError != null) {
60        reject(checkError);
61        return;
62      }
63
64      console.log('Caller call msgData rpc.MessageSequence create');
65      let msgData = this.buildMsgData(method, data);
66      let msgReply = rpc.MessageSequence.create();
67
68      let retData = undefined;
69      try {
70        retData = await this.__call_obj__.callee.sendMessageRequest(EVENT_CALL_NOTIFY, msgData, msgReply,
71          rpc.MessageOption());
72        console.log('Caller call msgData rpc.sendMessageRequest called');
73        if (retData.errCode !== 0) {
74          msgData.reclaim();
75          msgReply.reclaim();
76          console.log('Caller call return errCode ' + retData.errCode);
77          reject(new BusinessError(retData.errCode));
78          return;
79        }
80      } catch (e) {
81        console.log('Caller call msgData rpc.sendMessageRequest error ' + e);
82      }
83
84      try {
85        let retval = retData.reply.readInt();
86        let str = retData.reply.readString();
87        if (retval === REQUEST_SUCCESS && str === 'object') {
88          msgData.reclaim();
89          msgReply.reclaim();
90        } else {
91          console.log('Caller call retval is [' + retval + '], str [' + str + ']');
92          msgData.reclaim();
93          msgReply.reclaim();
94          reject(new BusinessError(retval));
95          return;
96        }
97      } catch (e) {
98        console.log('Caller call msgData sendMessageRequest retval error');
99        reject(new BusinessError(ERROR_CODE_INNER_ERROR));
100        return;
101      }
102
103      console.log('Caller call msgData sendMessageRequest end');
104      resolve(undefined);
105      return;
106    });
107  }
108
109  callWithResult(method, data) {
110    return new Promise(async (resolve, reject) => {
111      console.log('Caller callWithResult method [' + method + ']');
112      const checkError = this.callCheck(method, data);
113      if (checkError != null) {
114        reject(checkError);
115        return;
116      }
117
118      console.log('Caller callWithResult msgData rpc.MessageSequence create');
119      let msgData = this.buildMsgData(method, data);
120      let msgReply = rpc.MessageSequence.create();
121
122      let reply = undefined;
123      let retData = undefined;
124      try {
125        retData = await this.__call_obj__.callee.sendMessageRequest(EVENT_CALL_NOTIFY, msgData, msgReply,
126          rpc.MessageOption());
127        console.log('Caller callWithResult msgData rpc.sendMessageRequest called');
128        if (retData.errCode !== 0) {
129          msgData.reclaim();
130          msgReply.reclaim();
131          console.log('Caller callWithResult return errCode ' + retData.errCode);
132          reject(new BusinessError(retData.errCode));
133          return;
134        }
135      } catch (e) {
136        console.log('Caller call msgData rpc.MessageSequence error ' + e);
137      }
138
139      try {
140        let retval = retData.reply.readInt();
141        let str = retData.reply.readString();
142        if (retval === REQUEST_SUCCESS && str === 'object') {
143          msgData.reclaim();
144          reply = retData.reply;
145        } else {
146          console.log('Caller callWithResult retval is [' + retval + '], str [' + str + ']');
147          msgData.reclaim();
148          msgReply.reclaim();
149          reject(new BusinessError(retval));
150          return;
151        }
152      } catch (e) {
153        console.log('Caller callWithResult msgData sendMessageRequest retval error');
154        reject(new BusinessError(ERROR_CODE_INNER_ERROR));
155        return;
156      }
157
158      console.log('Caller callWithResult msgData sendMessageRequest end');
159      resolve(reply);
160      return;
161    });
162  }
163
164  release() {
165    console.log('Caller release js called.');
166    if (this.releaseState === true) {
167      console.log('Caller release remoteObj releaseState is true');
168      throw new BusinessError(ERROR_CODE_CALLER_RELEASED);
169    }
170
171    if (this.__call_obj__.callee == null) {
172      console.log('Caller release call remoteObj is released');
173      throw new BusinessError(ERROR_CODE_CLAAEE_INVALID);
174    }
175
176    this.releaseState = true;
177    this.__call_obj__.release();
178  }
179
180  onRelease(callback) {
181    console.log('Caller onRelease jscallback called.');
182    if (typeof callback !== 'function') {
183      console.log('Caller onRelease ' + typeof callback);
184      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
185    }
186
187    if (this.releaseState === true) {
188      console.log('Caller onRelease remoteObj releaseState is true');
189      throw new BusinessError(ERROR_CODE_CALLER_RELEASED);
190    }
191
192    this.__call_obj__.onRelease(callback);
193  }
194
195  onRemoteStateChange(callback) {
196    console.log('Caller onRemoteStateChange jscallback called.');
197    if (typeof callback !== 'function') {
198      console.log('Caller onRemoteStateChange ' + typeof callback);
199      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
200    }
201
202    if (this.releaseState === true) {
203      console.log('Caller onRemoteStateChange remoteObj releaseState is true');
204      throw new BusinessError(ERROR_CODE_CALLER_RELEASED);
205    }
206
207    this.__call_obj__.onRemoteStateChange(callback);
208  }
209
210  on(type, callback) {
211    console.log('Caller onRelease jscallback called.');
212    if (typeof type !== 'string' || type !== 'release') {
213      console.log(
214        'Caller onRelease error, input [type] is invalid.');
215      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
216    }
217
218    if (typeof callback !== 'function') {
219      console.log('Caller onRelease error ' + typeof callback);
220      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
221    }
222
223    if (this.releaseState === true) {
224      console.log('Caller onRelease error, remoteObj releaseState is true');
225      throw new BusinessError(ERROR_CODE_CALLER_RELEASED);
226    }
227
228    this.__call_obj__.onRelease(callback);
229  }
230
231  off(type, callback) {
232    if (typeof type !== 'string' || type !== 'release') {
233      console.log(
234        'Caller onRelease error, input [type] is invalid.');
235      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
236    }
237
238    if (callback && typeof callback !== 'function') {
239      console.log('Caller onRelease error ' + typeof callback);
240      throw new BusinessError(ERROR_CODE_INVALID_PARAM);
241    }
242    // Empty
243  }
244
245  callCheck(method, data) {
246    if (typeof method !== 'string' || typeof data !== 'object') {
247      console.log('Caller callCheck ' + typeof method + ' ' + typeof data);
248      return new BusinessError(ERROR_CODE_INVALID_PARAM);
249    }
250
251    if (method === '' || data == null) {
252      console.log('Caller callCheck ' + method + ', ' + data);
253      return new BusinessError(ERROR_CODE_INVALID_PARAM);
254    }
255
256    if (this.releaseState === true) {
257      console.log('Caller callCheck this.callee release');
258      return new BusinessError(ERROR_CODE_CALLER_RELEASED);
259    }
260
261    if (this.__call_obj__.callee == null) {
262      console.log('Caller callCheck this.callee is nullptr');
263      return new BusinessError(ERROR_CODE_CLAAEE_INVALID);
264    }
265    return null;
266  }
267
268  buildMsgData(method, data) {
269    let msgData = rpc.MessageSequence.create();
270    msgData.writeString(method);
271    msgData.writeParcelable(data);
272    return msgData;
273  }
274}
275
276export default Caller;
277