CallManager constructor

CallManager()

Implementation

CallManager() {
  NEEventNotify().register(setStateEventOnCallReceived, (arg) async {
    final launchContext = arg is Map<String, dynamic> ? arg : null;
    final isAppInForeground = (Platform.isAndroid || PlatformCompat.isOhos)
        ? await NECallKitPlatform.instance.isAppInForeground()
        : false;
    if (shouldPreflightIncomingPermissions(
      isAndroid: Platform.isAndroid,
      isIOS: Platform.isIOS,
      isOhos: PlatformCompat.isOhos,
      isDesktopRuntime: _isDesktopRuntime,
      isAppInForeground: isAppInForeground,
    )) {
      if (_enableIncomingBanner &&
          CallState.instance.selfUser.callRole == NECallRole.called) {
        // 并发来电检查:若横幅已显示,说明已有一路来电,新来电回复忙线并丢弃
        if (_bannerIsActive) {
          CallKitUILog.i(_tag, 'secondCallIgnored replyBusy');
          await NECallEngine.instance.hangup();
          return;
        }
        CallKitUILog.i(_tag, 'showIncomingBanner enableIncomingBanner=true');
        _bannerIsActive = true;
        // 先同步来电方信息到 native,确保原生层有最新数据再展示横幅
        _syncCallStateToNative();
        await NECallKitPlatform.instance.setIncomingBannerEnabled(true);
        // Android/Ohos: 直接调用 showIncomingBanner() 触发横幅展示
        // iOS 层由 NEFlutterIncomingBannerHandler 响应并展示 NEIncomingCallBannerWindow
        if (Platform.isAndroid || PlatformCompat.isOhos) {
          await NECallKitPlatform.instance.showIncomingBanner();
        }

        // 注册 onCallEnd 监听:通话结束时自动取消横幅并重置活跃状态
        void onCallEndHandler(dynamic arg) {
          CallKitUILog.i(_tag, 'dismissIncomingBanner reason=callEnded');
          NECallKitPlatform.instance.cancelIncomingBanner();
          _bannerIsActive = false;
          NEEventNotify().unregister(
            setStateEventOnCallEnd,
            onCallEndHandler,
          );
        }

        NEEventNotify().register(setStateEventOnCallEnd, onCallEndHandler);

        return;
      }
      _enterCallingPage(
        'incoming_call_foreground',
        launchContext: launchContext,
      );
      // iOS 在来电进入页面后立即申请权限,权限不足则直接拒接。
      // Desktop 复用这条策略,避免权限关闭后仍停留在等待手动接听的状态。
      var permissionResult = await _runtimeAdapter.requestPermissions(
        CallState.instance.callType,
      );
      if (PermissionResult.granted == permissionResult) {
      } else {
        CallManager.instance.reject();
        _runtimeAdapter.stopRing();
      }
    } else {
      _enterCallingPage(
        'incoming_call_background',
        launchContext: launchContext,
      );
    }
  });
}