1e484b35bSopenharmony_ci/* 2e484b35bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3e484b35bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e484b35bSopenharmony_ci * you may not use this file except in compliance with the License. 5e484b35bSopenharmony_ci * You may obtain a copy of the License at 6e484b35bSopenharmony_ci * 7e484b35bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e484b35bSopenharmony_ci * 9e484b35bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e484b35bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e484b35bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e484b35bSopenharmony_ci * See the License for the specific language governing permissions and 13e484b35bSopenharmony_ci * limitations under the License. 14e484b35bSopenharmony_ci */ 15e484b35bSopenharmony_ci 16e484b35bSopenharmony_ci/** 17e484b35bSopenharmony_ci * Intercept callback from native and forward to user-defined callback. 18e484b35bSopenharmony_ci * @param {*} args - Args. 19e484b35bSopenharmony_ci * @param {boolean} [needPromise] - If asynchronous operations are needed. 20e484b35bSopenharmony_ci * @return {Object} If promise are needed, return { args, promise }. Otherwise return args. 21e484b35bSopenharmony_ci */ 22e484b35bSopenharmony_ciexport function interceptCallback(args: any, needPromise?: boolean): object { 23e484b35bSopenharmony_ci if (args.length === 0 && !needPromise) { 24e484b35bSopenharmony_ci return args; 25e484b35bSopenharmony_ci } 26e484b35bSopenharmony_ci const first: object = args[0]; 27e484b35bSopenharmony_ci const callbacks: object = {}; 28e484b35bSopenharmony_ci let hasProperty: boolean = false; 29e484b35bSopenharmony_ci if (typeof first === 'object' && 30e484b35bSopenharmony_ci Object.prototype.toString.call(first).toLowerCase() === '[object object]' && 31e484b35bSopenharmony_ci args.length === 1 32e484b35bSopenharmony_ci ) { 33e484b35bSopenharmony_ci for (const key in first) { 34e484b35bSopenharmony_ci const value: Function = first[key]; 35e484b35bSopenharmony_ci if (typeof value === 'function') { 36e484b35bSopenharmony_ci callbacks[key] = value; 37e484b35bSopenharmony_ci } else { 38e484b35bSopenharmony_ci hasProperty = true; 39e484b35bSopenharmony_ci } 40e484b35bSopenharmony_ci } 41e484b35bSopenharmony_ci } else { 42e484b35bSopenharmony_ci hasProperty = true; 43e484b35bSopenharmony_ci } 44e484b35bSopenharmony_ci 45e484b35bSopenharmony_ci let promise: any; 46e484b35bSopenharmony_ci const callbLength: number = Object.keys(callbacks).length; 47e484b35bSopenharmony_ci if (needPromise) { 48e484b35bSopenharmony_ci if (callbLength <= 0) { 49e484b35bSopenharmony_ci promise = new PromiseRef(); 50e484b35bSopenharmony_ci } 51e484b35bSopenharmony_ci } 52e484b35bSopenharmony_ci if (callbLength > 0 || promise) { 53e484b35bSopenharmony_ci const callb = (msg: { method: string; arguments: any; }) => { 54e484b35bSopenharmony_ci let func = callbacks[msg.method]; 55e484b35bSopenharmony_ci const callbArgs: any = msg.arguments; 56e484b35bSopenharmony_ci 57e484b35bSopenharmony_ci if (func !== undefined) { 58e484b35bSopenharmony_ci func(...callbArgs); 59e484b35bSopenharmony_ci } 60e484b35bSopenharmony_ci 61e484b35bSopenharmony_ci // Always call complete(). 62e484b35bSopenharmony_ci func = callbacks['complete']; 63e484b35bSopenharmony_ci if (func !== undefined) { 64e484b35bSopenharmony_ci func(...callbArgs); 65e484b35bSopenharmony_ci } 66e484b35bSopenharmony_ci if (promise) { 67e484b35bSopenharmony_ci const data: any = callbArgs && 68e484b35bSopenharmony_ci callbArgs.length > 0 69e484b35bSopenharmony_ci ? callbArgs[0] 70e484b35bSopenharmony_ci : undefined; 71e484b35bSopenharmony_ci if ('success' === msg.method || 'callback' === msg.method) { 72e484b35bSopenharmony_ci promise.resolve({ data }); 73e484b35bSopenharmony_ci } else { 74e484b35bSopenharmony_ci // 200 means common error ,100 :cancel. 75e484b35bSopenharmony_ci const code: any = 76e484b35bSopenharmony_ci 'cancel' === msg.method 77e484b35bSopenharmony_ci ? 100 78e484b35bSopenharmony_ci : callbArgs && callbArgs.length > 1 79e484b35bSopenharmony_ci ? callbArgs[1] 80e484b35bSopenharmony_ci : 200; 81e484b35bSopenharmony_ci promise.reject({ data, code }); 82e484b35bSopenharmony_ci } 83e484b35bSopenharmony_ci } 84e484b35bSopenharmony_ci }; 85e484b35bSopenharmony_ci callb.__onlyPromise = callbLength <= 0; 86e484b35bSopenharmony_ci 87e484b35bSopenharmony_ci if (hasProperty) { 88e484b35bSopenharmony_ci args.push(callb); 89e484b35bSopenharmony_ci } else { 90e484b35bSopenharmony_ci args = [callb]; 91e484b35bSopenharmony_ci } 92e484b35bSopenharmony_ci } 93e484b35bSopenharmony_ci return needPromise ? { args, promise } : args; 94e484b35bSopenharmony_ci} 95e484b35bSopenharmony_ci 96e484b35bSopenharmony_ci/** 97e484b35bSopenharmony_ci * This class provide a Promise object for asynchronous operation processing. 98e484b35bSopenharmony_ci */ 99e484b35bSopenharmony_ciclass PromiseRef { 100e484b35bSopenharmony_ci private _promise: Promise<object>; 101e484b35bSopenharmony_ci private _reject: Function; 102e484b35bSopenharmony_ci private _resolve: Function; 103e484b35bSopenharmony_ci 104e484b35bSopenharmony_ci constructor() { 105e484b35bSopenharmony_ci this._promise = new Promise((resolve, reject) => { 106e484b35bSopenharmony_ci this._reject = reject; 107e484b35bSopenharmony_ci this._resolve = resolve; 108e484b35bSopenharmony_ci }); 109e484b35bSopenharmony_ci } 110e484b35bSopenharmony_ci 111e484b35bSopenharmony_ci /** 112e484b35bSopenharmony_ci * Promise of this PromiseRef. 113e484b35bSopenharmony_ci * @type {Promise} 114e484b35bSopenharmony_ci */ 115e484b35bSopenharmony_ci public get promise() { 116e484b35bSopenharmony_ci return this._promise; 117e484b35bSopenharmony_ci } 118e484b35bSopenharmony_ci 119e484b35bSopenharmony_ci public set promise(newPromise) { 120e484b35bSopenharmony_ci this._promise = newPromise; 121e484b35bSopenharmony_ci } 122e484b35bSopenharmony_ci 123e484b35bSopenharmony_ci /** 124e484b35bSopenharmony_ci * Reject function using the Promise object. 125e484b35bSopenharmony_ci * @type {Promise} 126e484b35bSopenharmony_ci */ 127e484b35bSopenharmony_ci public get reject() { 128e484b35bSopenharmony_ci return this._reject; 129e484b35bSopenharmony_ci } 130e484b35bSopenharmony_ci 131e484b35bSopenharmony_ci public set reject(data) { 132e484b35bSopenharmony_ci this._reject = data; 133e484b35bSopenharmony_ci } 134e484b35bSopenharmony_ci 135e484b35bSopenharmony_ci /** 136e484b35bSopenharmony_ci * Resolve function using the Promise object. 137e484b35bSopenharmony_ci * @type {Promise} 138e484b35bSopenharmony_ci */ 139e484b35bSopenharmony_ci public get resolve() { 140e484b35bSopenharmony_ci return this._resolve; 141e484b35bSopenharmony_ci } 142e484b35bSopenharmony_ci 143e484b35bSopenharmony_ci public set resolve(data) { 144e484b35bSopenharmony_ci this._resolve = data; 145e484b35bSopenharmony_ci } 146e484b35bSopenharmony_ci} 147