/*
 *  Copyright 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import android.content.Context;
import android.os.Process;
import androidx.annotation.Nullable;
import java.util.List;
import org.jni_zero.NativeMethods;
import org.webrtc.Logging.Severity;
import org.webrtc.audio.AudioDeviceModule;
import org.webrtc.audio.JavaAudioDeviceModule;

/**
 * Java wrapper for a C++ PeerConnectionFactoryInterface.  Main entry point to
 * the PeerConnection API for clients.
 */
public class PeerConnectionFactory {
  public static final String TRIAL_ENABLED = "Enabled";
  @Deprecated public static final String VIDEO_FRAME_EMIT_TRIAL = "VideoFrameEmit";

  private static final String TAG = "PeerConnectionFactory";

  /** Helper class holding both Java and C++ thread info. */
  private static class ThreadInfo {
    final Thread thread;
    final int tid;

    public static ThreadInfo getCurrent() {
      return new ThreadInfo(Thread.currentThread(), Process.myTid());
    }

    private ThreadInfo(Thread thread, int tid) {
      this.thread = thread;
      this.tid = tid;
    }
  }

  private static volatile boolean internalTracerInitialized;

  // Remove these once deprecated static printStackTrace() is gone.
  @Nullable private static ThreadInfo staticNetworkThread;
  @Nullable private static ThreadInfo staticWorkerThread;
  @Nullable private static ThreadInfo staticSignalingThread;

  private final NativeLifecycleLock lifecycleLock;
  @Nullable private volatile ThreadInfo networkThread;
  @Nullable private volatile ThreadInfo workerThread;
  @Nullable private volatile ThreadInfo signalingThread;

  public static class InitializationOptions {
    final Context applicationContext;
    final String fieldTrials;
    final boolean enableInternalTracer;
    final NativeLibraryLoader nativeLibraryLoader;
    final String nativeLibraryName;
    @Nullable Loggable loggable;
    @Nullable Severity loggableSeverity;

    private InitializationOptions(Context applicationContext, String fieldTrials,
        boolean enableInternalTracer, NativeLibraryLoader nativeLibraryLoader,
        String nativeLibraryName, @Nullable Loggable loggable,
        @Nullable Severity loggableSeverity) {
      this.applicationContext = applicationContext;
      this.fieldTrials = fieldTrials;
      this.enableInternalTracer = enableInternalTracer;
      this.nativeLibraryLoader = nativeLibraryLoader;
      this.nativeLibraryName = nativeLibraryName;
      this.loggable = loggable;
      this.loggableSeverity = loggableSeverity;
    }

    public static Builder builder(Context applicationContext) {
      return new Builder(applicationContext);
    }

    public static class Builder {
      private final Context applicationContext;
      private String fieldTrials = "";
      private boolean enableInternalTracer;
      private NativeLibraryLoader nativeLibraryLoader = new NativeLibrary.DefaultLoader();
      private String nativeLibraryName = "jingle_peerconnection_so";
      @Nullable private Loggable loggable;
      @Nullable private Severity loggableSeverity;

      Builder(Context applicationContext) {
        this.applicationContext = applicationContext;
      }

      // Deprecated, use PeerConnectionFactory.Builder.setFieldTrials instead.
      // TODO: bugs.webrtc.org/42220378 - Delete after January 1, 2026.
      @Deprecated
      public Builder setFieldTrials(String fieldTrials) {
        this.fieldTrials = fieldTrials;
        return this;
      }

      public Builder setEnableInternalTracer(boolean enableInternalTracer) {
        this.enableInternalTracer = enableInternalTracer;
        return this;
      }

      public Builder setNativeLibraryLoader(NativeLibraryLoader nativeLibraryLoader) {
        this.nativeLibraryLoader = nativeLibraryLoader;
        return this;
      }

      public Builder setNativeLibraryName(String nativeLibraryName) {
        this.nativeLibraryName = nativeLibraryName;
        return this;
      }

      public Builder setInjectableLogger(Loggable loggable, Severity severity) {
        this.loggable = loggable;
        this.loggableSeverity = severity;
        return this;
      }

      public PeerConnectionFactory.InitializationOptions createInitializationOptions() {
        return new PeerConnectionFactory.InitializationOptions(applicationContext, fieldTrials,
            enableInternalTracer, nativeLibraryLoader, nativeLibraryName, loggable,
            loggableSeverity);
      }
    }
  }

  public static class Options {
    // Keep in sync with webrtc/rtc_base/network.h!
    //
    // These bit fields are defined for `networkIgnoreMask` below.
    public static final int ADAPTER_TYPE_UNKNOWN = 0;
    public static final int ADAPTER_TYPE_ETHERNET = 1 << 0;
    public static final int ADAPTER_TYPE_WIFI = 1 << 1;
    public static final int ADAPTER_TYPE_CELLULAR = 1 << 2;
    public static final int ADAPTER_TYPE_VPN = 1 << 3;
    public static final int ADAPTER_TYPE_LOOPBACK = 1 << 4;
    public static final int ADAPTER_TYPE_ANY = 1 << 5;

    public int networkIgnoreMask;
    public boolean disableEncryption;
    public boolean disableNetworkMonitor;

    @CalledByNative
    int getNetworkIgnoreMask() {
      return networkIgnoreMask;
    }

    @CalledByNative
    boolean getDisableEncryption() {
      return disableEncryption;
    }

    @CalledByNative
    boolean getDisableNetworkMonitor() {
      return disableNetworkMonitor;
    }
  }

  public static class Builder {
    @Nullable private Options options;
    private final Environment.Builder envBuilder = Environment.builder();
    @Nullable private AudioDeviceModule audioDeviceModule;
    private AudioEncoderFactoryFactory audioEncoderFactoryFactory =
        new BuiltinAudioEncoderFactoryFactory();
    private AudioDecoderFactoryFactory audioDecoderFactoryFactory =
        new BuiltinAudioDecoderFactoryFactory();
    @Nullable private VideoEncoderFactory videoEncoderFactory;
    @Nullable private VideoDecoderFactory videoDecoderFactory;
    @Nullable private AudioProcessingFactory audioProcessingFactory;
    @Nullable private FecControllerFactoryFactoryInterface fecControllerFactoryFactory;
    @Nullable private NetworkControllerFactoryFactory networkControllerFactoryFactory;
    @Nullable private NetworkStatePredictorFactoryFactory networkStatePredictorFactoryFactory;
    @Nullable private NetEqFactoryFactory neteqFactoryFactory;
    @Nullable private AudioFrameProcessor audioFrameProcessor;

    private Builder() {}

    public Builder setOptions(Options options) {
      this.options = options;
      return this;
    }

    public Builder setFieldTrials(String fieldTrials) {
      envBuilder.setFieldTrials(fieldTrials);
      return this;
    }

    public Builder setAudioDeviceModule(AudioDeviceModule audioDeviceModule) {
      this.audioDeviceModule = audioDeviceModule;
      return this;
    }

    public Builder setAudioEncoderFactoryFactory(
        AudioEncoderFactoryFactory audioEncoderFactoryFactory) {
      if (audioEncoderFactoryFactory == null) {
        throw new IllegalArgumentException(
            "PeerConnectionFactory.Builder does not accept a null AudioEncoderFactoryFactory.");
      }
      this.audioEncoderFactoryFactory = audioEncoderFactoryFactory;
      return this;
    }

    public Builder setAudioDecoderFactoryFactory(
        AudioDecoderFactoryFactory audioDecoderFactoryFactory) {
      if (audioDecoderFactoryFactory == null) {
        throw new IllegalArgumentException(
            "PeerConnectionFactory.Builder does not accept a null AudioDecoderFactoryFactory.");
      }
      this.audioDecoderFactoryFactory = audioDecoderFactoryFactory;
      return this;
    }

    public Builder setVideoEncoderFactory(VideoEncoderFactory videoEncoderFactory) {
      this.videoEncoderFactory = videoEncoderFactory;
      return this;
    }

    public Builder setVideoDecoderFactory(VideoDecoderFactory videoDecoderFactory) {
      this.videoDecoderFactory = videoDecoderFactory;
      return this;
    }

    public Builder setAudioProcessingFactory(AudioProcessingFactory audioProcessingFactory) {
      if (audioProcessingFactory == null) {
        throw new NullPointerException(
            "PeerConnectionFactory builder does not accept a null AudioProcessingFactory.");
      }
      this.audioProcessingFactory = audioProcessingFactory;
      return this;
    }

    public Builder setFecControllerFactoryFactoryInterface(
        FecControllerFactoryFactoryInterface fecControllerFactoryFactory) {
      this.fecControllerFactoryFactory = fecControllerFactoryFactory;
      return this;
    }

    public Builder setNetworkControllerFactoryFactory(
        NetworkControllerFactoryFactory networkControllerFactoryFactory) {
      this.networkControllerFactoryFactory = networkControllerFactoryFactory;
      return this;
    }

    public Builder setNetworkStatePredictorFactoryFactory(
        NetworkStatePredictorFactoryFactory networkStatePredictorFactoryFactory) {
      this.networkStatePredictorFactoryFactory = networkStatePredictorFactoryFactory;
      return this;
    }

    /**
     * Sets a NetEqFactoryFactory for the PeerConnectionFactory. When using a
     * custom NetEqFactoryFactory, the AudioDecoderFactoryFactory will be set
     * to null. The AudioDecoderFactoryFactory should be wrapped in the
     * NetEqFactoryFactory.
     */
    public Builder setNetEqFactoryFactory(NetEqFactoryFactory neteqFactoryFactory) {
      this.neteqFactoryFactory = neteqFactoryFactory;
      return this;
    }

    /**
     * Sets an AudioFrameProcessor for the PeerConnectionFactory.
     *
     * <p>This is used to process audio frames before they are sent to the audio device module.
     */
    public Builder setAudioFrameProcessor(AudioFrameProcessor audioFrameProcessor) {
      this.audioFrameProcessor = audioFrameProcessor;
      return this;
    }

    public PeerConnectionFactory createPeerConnectionFactory() {
      checkInitializeHasBeenCalled();
      try (Environment env = envBuilder.build()) {
        if (audioDeviceModule == null) {
          audioDeviceModule = JavaAudioDeviceModule.builder(ContextUtils.getApplicationContext())
                                  .createAudioDeviceModule();
        }
        return PeerConnectionFactoryJni.get()
            .createPeerConnectionFactory(
                ContextUtils.getApplicationContext(),
                options,
                env.ref(),
                audioDeviceModule.getNative(env.ref()),
                audioEncoderFactoryFactory.createNativeAudioEncoderFactory(),
                audioDecoderFactoryFactory.createNativeAudioDecoderFactory(),
                videoEncoderFactory,
                videoDecoderFactory,
                audioProcessingFactory == null ? 0 : audioProcessingFactory.createNative(env.ref()),
                fecControllerFactoryFactory == null
                    ? 0
                    : fecControllerFactoryFactory.createNative(),
                networkControllerFactoryFactory == null
                    ? 0
                    : networkControllerFactoryFactory.createNativeNetworkControllerFactory(),
                networkStatePredictorFactoryFactory == null
                    ? 0
                    : networkStatePredictorFactoryFactory
                        .createNativeNetworkStatePredictorFactory(),
                neteqFactoryFactory == null ? 0 : neteqFactoryFactory.createNativeNetEqFactory(),
                audioFrameProcessor == null
                    ? 0
                    : audioFrameProcessor.getNativeAudioFrameProcessor());
      }
    }
  }

  public static Builder builder() {
    return new Builder();
  }

  /**
   * Loads and initializes WebRTC. This must be called at least once before creating a
   * PeerConnectionFactory. Replaces all the old initialization methods. Must not be called while
   * a PeerConnectionFactory is alive.
   */
  @SuppressWarnings("EnumOrdinal")
  public static void initialize(InitializationOptions options) {
    ContextUtils.initialize(options.applicationContext);
    NativeLibrary.initialize(options.nativeLibraryLoader, options.nativeLibraryName);
    PeerConnectionFactoryJni.get().initializeAndroidGlobals();
    PeerConnectionFactoryJni.get().initializeFieldTrials(options.fieldTrials);
    if (options.enableInternalTracer && !internalTracerInitialized) {
      initializeInternalTracer();
    }
    if (options.loggable != null) {
      Logging.injectLoggable(options.loggable, options.loggableSeverity);
      PeerConnectionFactoryJni.get()
          .injectLoggable(new JNILogging(options.loggable), options.loggableSeverity.ordinal());
    } else {
      Logging.d(TAG,
          "PeerConnectionFactory was initialized without an injected Loggable. "
              + "Any existing Loggable will be deleted.");
      Logging.deleteInjectedLoggable();
      PeerConnectionFactoryJni.get().deleteLoggable();
    }
  }

  private static void checkInitializeHasBeenCalled() {
    if (!NativeLibrary.isLoaded() || ContextUtils.getApplicationContext() == null) {
      throw new IllegalStateException(
          "PeerConnectionFactory.initialize was not called before creating a "
          + "PeerConnectionFactory.");
    }
  }

  private static void initializeInternalTracer() {
    internalTracerInitialized = true;
    PeerConnectionFactoryJni.get().initializeInternalTracer();
  }

  public static void shutdownInternalTracer() {
    internalTracerInitialized = false;
    PeerConnectionFactoryJni.get().shutdownInternalTracer();
  }

  // Field trial initialization. Must be called before PeerConnectionFactory
  // is created.
  // Deprecated, use PeerConnectionFactory.Builder.setFieldTrials instead.
  // TODO: bugs.webrtc.org/42220378 - Delete after January 1, 2026.
  @Deprecated
  public static void initializeFieldTrials(String fieldTrialsInitString) {
    PeerConnectionFactoryJni.get().initializeFieldTrials(fieldTrialsInitString);
  }

  // Start/stop internal capturing of internal tracing.
  public static boolean startInternalTracingCapture(String tracingFilename) {
    return PeerConnectionFactoryJni.get().startInternalTracingCapture(tracingFilename);
  }

  public static void stopInternalTracingCapture() {
    PeerConnectionFactoryJni.get().stopInternalTracingCapture();
  }

  @CalledByNative
  PeerConnectionFactory(long nativeFactory) {
    checkInitializeHasBeenCalled();
    if (nativeFactory == 0) {
      throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
    }
    this.lifecycleLock = new NativeLifecycleLock("PeerConnectionFactory", nativeFactory);
  }

  /**
   * Internal helper function to pass the parameters down into the native JNI bridge.
   */
  @Nullable
  PeerConnection createPeerConnectionInternal(PeerConnection.RTCConfiguration rtcConfig,
      MediaConstraints constraints, PeerConnection.Observer observer,
      SSLCertificateVerifier sslCertificateVerifier) {
    return lifecycleLock.call(factory -> {
      long nativeObserver = PeerConnection.createNativePeerConnectionObserver(observer);
      if (nativeObserver == 0) {
        return null;
      }
      long nativePeerConnection =
          PeerConnectionFactoryJni.get()
              .createPeerConnection(
                  factory, rtcConfig, constraints, nativeObserver, sslCertificateVerifier);
      if (nativePeerConnection == 0) {
        return null;
      }
      return new PeerConnection(nativePeerConnection);
    });
  }

  /**
   * Deprecated. PeerConnection constraints are deprecated. Supply values in rtcConfig struct
   * instead and use the method without constraints in the signature.
   */
  @Nullable
  @Deprecated
  public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
      MediaConstraints constraints, PeerConnection.Observer observer) {
    return createPeerConnectionInternal(
        rtcConfig, constraints, observer, /* sslCertificateVerifier= */ null);
  }

  /**
   * Deprecated. PeerConnection constraints are deprecated. Supply values in rtcConfig struct
   * instead and use the method without constraints in the signature.
   */
  @Nullable
  @Deprecated
  public PeerConnection createPeerConnection(List<PeerConnection.IceServer> iceServers,
      MediaConstraints constraints, PeerConnection.Observer observer) {
    PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
    rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
    return createPeerConnection(rtcConfig, constraints, observer);
  }

  @Nullable
  public PeerConnection createPeerConnection(
      List<PeerConnection.IceServer> iceServers, PeerConnection.Observer observer) {
    PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
    rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
    return createPeerConnection(rtcConfig, observer);
  }

  @Nullable
  public PeerConnection createPeerConnection(
      PeerConnection.RTCConfiguration rtcConfig, PeerConnection.Observer observer) {
    return createPeerConnection(rtcConfig, null /* constraints */, observer);
  }

  @Nullable
  public PeerConnection createPeerConnection(
      PeerConnection.RTCConfiguration rtcConfig, PeerConnectionDependencies dependencies) {
    return createPeerConnectionInternal(rtcConfig, null /* constraints */,
        dependencies.getObserver(), dependencies.getSSLCertificateVerifier());
  }

  public MediaStream createLocalMediaStream(String label) {
    return lifecycleLock.call(
        factory -> new MediaStream(
            PeerConnectionFactoryJni.get().createLocalMediaStream(factory, label)));
  }

  /**
   * Create video source with given parameters. If alignTimestamps is false, the caller is
   * responsible for aligning the frame timestamps to webrtc::TimeNanos(). This can be used to achieve
   * higher accuracy if there is a big delay between frame creation and frames being delivered to
   * the returned video source. If alignTimestamps is true, timestamps will be aligned to
   * webrtc::TimeNanos() when they arrive to the returned video source.
   */
  public VideoSource createVideoSource(boolean isScreencast, boolean alignTimestamps) {
    return lifecycleLock.call(
        factory -> new VideoSource(
            PeerConnectionFactoryJni.get()
                .createVideoSource(factory, isScreencast, alignTimestamps)));
  }

  /**
   * Same as above with alignTimestamps set to true.
   *
   * @see #createVideoSource(boolean, boolean)
   */
  public VideoSource createVideoSource(boolean isScreencast) {
    return createVideoSource(isScreencast, /* alignTimestamps= */ true);
  }

  public VideoTrack createVideoTrack(String id, VideoSource source) {
    return lifecycleLock.call(
        factory ->
            source.lifecycleLock.call(
                nativeSource ->
                    new VideoTrack(
                        PeerConnectionFactoryJni.get()
                            .createVideoTrack(factory, id, nativeSource))));
  }

  public AudioSource createAudioSource(MediaConstraints constraints) {
    return lifecycleLock.call(
        factory -> new AudioSource(
            PeerConnectionFactoryJni.get().createAudioSource(factory, constraints)));
  }

  public AudioTrack createAudioTrack(String id, AudioSource source) {
    return lifecycleLock.call(
        factory ->
            source.lifecycleLock.call(
                nativeSource ->
                    new AudioTrack(
                        PeerConnectionFactoryJni.get()
                            .createAudioTrack(factory, id, nativeSource))));
  }

  public RtpCapabilities getRtpReceiverCapabilities(MediaStreamTrack.MediaType mediaType) {
    return lifecycleLock.call(
        factory -> PeerConnectionFactoryJni.get()
                       .getRtpReceiverCapabilities(factory, mediaType));
  }

  public RtpCapabilities getRtpSenderCapabilities(MediaStreamTrack.MediaType mediaType) {
    return lifecycleLock.call(
        factory -> PeerConnectionFactoryJni.get()
                       .getRtpSenderCapabilities(factory, mediaType));
  }

  // Starts recording an AEC dump. Ownership of the file is transfered to the
  // native code. If an AEC dump is already in progress, it will be stopped and
  // a new one will start using the provided file.
  public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
    return lifecycleLock.call(
        factory -> PeerConnectionFactoryJni.get()
            .startAecDump(factory, file_descriptor, filesize_limit_bytes));
  }

  // Stops recording an AEC dump. If no AEC dump is currently being recorded,
  // this call will have no effect.
  public void stopAecDump() {
    lifecycleLock.runIfAlive(factory -> PeerConnectionFactoryJni.get().stopAecDump(factory));
  }

  public void dispose() {
    lifecycleLock.dispose(factory -> PeerConnectionFactoryJni.get().freeFactory(factory));
    networkThread = null;
    workerThread = null;
    signalingThread = null;
  }

  /** Returns a pointer to the native webrtc::PeerConnectionFactoryInterface. */
  public long getNativePeerConnectionFactory() {
    return lifecycleLock.call(
        factory -> PeerConnectionFactoryJni.get().getNativePeerConnectionFactory(factory));
  }

  /** Returns a pointer to the native OwnedFactoryAndThreads object */
  public long getNativeOwnedFactoryAndThreads() {
    return lifecycleLock.getNativePointer();
  }

  private static void printStackTrace(
      @Nullable ThreadInfo threadInfo, boolean printNativeStackTrace) {
    if (threadInfo == null) {
      // Thread callbacks have not been completed yet, ignore call.
      return;
    }
    final String threadName = threadInfo.thread.getName();
    StackTraceElement[] stackTraces = threadInfo.thread.getStackTrace();
    if (stackTraces.length > 0) {
      Logging.w(TAG, threadName + " stacktrace:");
      for (StackTraceElement stackTrace : stackTraces) {
        Logging.w(TAG, stackTrace.toString());
      }
    }
    if (printNativeStackTrace) {
      // Imitate output from debuggerd/tombstone so that stack trace can easily be symbolized with
      // ndk-stack.
      Logging.w(TAG, "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***");
      Logging.w(TAG,
          "pid: " + Process.myPid() + ", tid: " + threadInfo.tid + ", name: " + threadName
              + "  >>> WebRTC <<<");
      PeerConnectionFactoryJni.get().printStackTrace(threadInfo.tid);
    }
  }

  /** Deprecated, use non-static version instead. */
  @Deprecated
  public static void printStackTraces() {
    printStackTrace(staticNetworkThread, /* printNativeStackTrace= */ false);
    printStackTrace(staticWorkerThread, /* printNativeStackTrace= */ false);
    printStackTrace(staticSignalingThread, /* printNativeStackTrace= */ false);
  }

  /**
   * Print the Java stack traces for the critical threads used by PeerConnectionFactory, namely;
   * signaling thread, worker thread, and network thread. If printNativeStackTraces is true, also
   * attempt to print the C++ stack traces for these threads.
   */
  public void printInternalStackTraces(boolean printNativeStackTraces) {
    printStackTrace(signalingThread, printNativeStackTraces);
    printStackTrace(workerThread, printNativeStackTraces);
    printStackTrace(networkThread, printNativeStackTraces);
  }

  @CalledByNative
  private void onNetworkThreadReady() {
    networkThread = ThreadInfo.getCurrent();
    staticNetworkThread = networkThread;
    Logging.d(TAG, "onNetworkThreadReady");
  }

  @CalledByNative
  private void onWorkerThreadReady() {
    workerThread = ThreadInfo.getCurrent();
    staticWorkerThread = workerThread;
    Logging.d(TAG, "onWorkerThreadReady");
  }

  @CalledByNative
  private void onSignalingThreadReady() {
    signalingThread = ThreadInfo.getCurrent();
    staticSignalingThread = signalingThread;
    Logging.d(TAG, "onSignalingThreadReady");
  }

  @NativeMethods
  interface Natives {
    void initializeAndroidGlobals();

    void initializeFieldTrials(String fieldTrialsInitString);

    void initializeInternalTracer();

    void shutdownInternalTracer();

    boolean startInternalTracingCapture(String tracingFilename);

    void stopInternalTracingCapture();

    PeerConnectionFactory createPeerConnectionFactory(
        Context context,
        Options options,
        long webrtcEnvRef,
        long nativeAudioDeviceModule,
        long audioEncoderFactory,
        long audioDecoderFactory,
        VideoEncoderFactory encoderFactory,
        VideoDecoderFactory decoderFactory,
        long nativeAudioProcessor,
        long nativeFecControllerFactory,
        long nativeNetworkControllerFactory,
        long nativeNetworkStatePredictorFactory,
        long neteqFactory,
        long nativeAudioFrameProcessor);

    long createPeerConnection(
        long factory,
        PeerConnection.RTCConfiguration rtcConfig,
        MediaConstraints constraints,
        long nativeObserver,
        SSLCertificateVerifier sslCertificateVerifier);

    long createLocalMediaStream(long factory, String label);

    long createVideoSource(long factory, boolean is_screencast, boolean alignTimestamps);

    long createVideoTrack(long factory, String id, long nativeVideoSource);

    long createAudioSource(long factory, MediaConstraints constraints);

    long createAudioTrack(long factory, String id, long nativeSource);

    boolean startAecDump(long factory, int file_descriptor, int filesize_limit_bytes);

    void stopAecDump(long factory);

    void freeFactory(long factory);

    long getNativePeerConnectionFactory(long factory);

    void injectLoggable(JNILogging jniLogging, int severity);

    void deleteLoggable();

    void printStackTrace(int tid);

    RtpCapabilities getRtpSenderCapabilities(long factory, MediaStreamTrack.MediaType mediaType);

    RtpCapabilities getRtpReceiverCapabilities(long factory, MediaStreamTrack.MediaType mediaType);
  }
}
