async _transferFiles({ cmdArgs, onError, onProgress, onCompleted }) {
    try {
      checkIf(cmdArgs, 'array');
      checkIf(onError, 'function');
      checkIf(onProgress, 'function');
      checkIf(onCompleted, 'function');

      const handletransferListTimeInterval = 1000;
      let transferList = {};
      let prevCopiedBlockSize = 0;
      let currentCopiedBlockSize = 0;
      let startTime = 0;
      let prevCopiedTime = 0;
      let currentCopiedTime = 0;
      let bufferedOutput = null;

      let handleTransferListInterval = setInterval(() => {
        if (transferList === null) {
          clearInterval(handleTransferListInterval);
          handleTransferListInterval = 0;

          return null;
        }

        if (Object.keys(transferList).length < 1) {
          return null;
        }

        const {
          percentage: _percentage,
          currentFile,
          activeFileSize,
          activeFileSizeSent,
        } = transferList;

        const copiedTimeDiff = currentCopiedTime - prevCopiedTime;
        const speed =
          prevCopiedBlockSize &&
          prevCopiedBlockSize - currentCopiedBlockSize > 0
            ? (prevCopiedBlockSize - currentCopiedBlockSize) *
              (1000 / copiedTimeDiff)
            : 0;
        const elapsedTime = msToTime(currentCopiedTime - startTime);

        prevCopiedTime = currentCopiedTime;
        prevCopiedBlockSize = currentCopiedBlockSize;

        onProgress({
          elapsedTime,
          speed,
          activeFileProgress: _percentage,
          currentFile,
          activeFileSize,
          activeFileSizeSent,
        });
      }, handletransferListTimeInterval);

      const cmd = spawn(this.mtpCli, [...cmdArgs], {
        shell: true,
      });

      cmd.stdout.on('data', (data) => {
        bufferedOutput = data.toString();

        if (startTime === 0) {
          startTime = unixTimestampNow();
        }

        if (
          typeof bufferedOutput === 'undefined' ||
          bufferedOutput === null ||
          bufferedOutput.length < 1
        ) {
          return null;
        }

        const _bufferedOutput = splitIntoLines(bufferedOutput).filter(
          (a, index) => !this._filterOutMtpLines(a, index)
        );

        if (_bufferedOutput.length < 1) {
          return null;
        }

        for (let i = 0; i < _bufferedOutput.length; i += 1) {
          const item = _bufferedOutput[i];
          const bufferedOutputSplit = item.split(' ');

          if (bufferedOutputSplit.length < 1) {
            return null;
          }

          const totalLength = bufferedOutputSplit.length;
          const eventIndex = 0;
          const filePathStartIndex = 1;
          const filePathEndIndex = totalLength - 3;
          const currentProgressSizeIndex = totalLength - 2;
          const totalFileSizeIndex = totalLength - 1;

          const event = bufferedOutputSplit[eventIndex];
          const matchedItem = item.match(/(\d+?\d*)\s(\d+?\d*)$/);

          if (matchedItem === null) {
            return null;
          }

          const matchedItemSplit = matchedItem[0].split(' ');
          const currentProgressSize = parseInt(matchedItemSplit[0], 10);
          const totalFileSize = parseInt(matchedItemSplit[1], 10);

          if (event === `:done`) {
            prevCopiedBlockSize = 0;
            currentCopiedBlockSize = 0;
            prevCopiedTime = 0;
            currentCopiedTime = 0;

            return null;
          }

          if (
            totalLength < 3 ||
            event !== `:progress` ||
            currentProgressSizeIndex < 2 ||
            totalFileSizeIndex < 3
          ) {
            return null;
          }

          const filePath = bufferedOutputSplit
            .slice(filePathStartIndex, filePathEndIndex + 1)
            .join(' ');

          const perc = percentage(currentProgressSize, totalFileSize);

          currentCopiedBlockSize = totalFileSize - currentProgressSize;
          currentCopiedTime = unixTimestampNow();

          transferList = {
            currentFile: filePath,
            activeFileSize: totalFileSize,
            activeFileSizeSent: currentProgressSize,
            percentage: perc,
            currentCopiedBlockSize,
            currentCopiedTime,
          };
        }
      });

      // capture error
      cmd.stderr.on('data', (error) => {
        const { filteredError } = this._cleanJunkMtpError({ error });

        if (undefinedOrNull(filteredError) || filteredError.length < 1) {
          return null;
        }

        onError({
          error,
          stderr: null,
          data: null,
        });

        transferList = null;
      });

      cmd.on('exit', () => {
        transferList = null;

        onCompleted();
      });

      return { error: null, stderr: null, data: true };
    } catch (e) {
      log.error(e);

      return { error: null, stderr: null, data: false };
    }
  }
description - file transfer helper

@param {[string]} cmdArgs - command line strings in an array
@param {errorCallback} onError
@param {progressCallback} onProgress
@param {completedCallback} onCompleted
@return {Promise<{data: boolean, error: string|null, stderr: string|null}>}
@private