content: package com.cicada.player.nativeclass;
  
  import android.content.Context;
  import android.view.Surface;
  
  import com.cicada.player.CicadaExternalPlayer;
  import com.cicada.player.CicadaPlayer;
  import com.cicada.player.utils.NativeLoader;
  import com.cicada.player.utils.NativeUsed;
  
  @NativeUsed
  public class NativeExternalPlayer {
  
      static {
          NativeLoader.loadPlayer();
      }
  
  
      private CicadaExternalPlayer mExternPlayer = null;
  
      private long mNativeInstance = 0;
  
      @NativeUsed
      public static boolean isSupport(Options options) {
          CicadaExternalPlayer dummyPlayer = CicadaExternalPlayer.isSupportExternal(options);
          if (dummyPlayer != null) {
              return true;
          } else {
              return false;
          }
      }
  
      private static Context sContext = null;
  
      public static void setContext(Context context) {
          if(sContext == null && context != null) {
              sContext = context.getApplicationContext();
          }
      }
  
      @NativeUsed
      public void create(long nativeAddr, Options options) {
          CicadaExternalPlayer dummyPlayer = CicadaExternalPlayer.isSupportExternal(options);
          if (dummyPlayer != null) {
              mExternPlayer = dummyPlayer.create(sContext, options);
          }
  
          if (mExternPlayer == null) {
              return;
          }
  
          mNativeInstance = nativeAddr;
  
          mExternPlayer.setOnPreparedListener(new CicadaExternalPlayer.OnPreparedListener() {
              @Override
              public void onPrepared() {
                  nativeOnPrepared(mNativeInstance);
              }
          });
          mExternPlayer.setOnLoopingStartListener(new CicadaExternalPlayer.OnLoopingStartListener() {
  
              @Override
              public void onLoopingStart() {
                  nativeOnLoopingStart(mNativeInstance);
              }
          });
  
          mExternPlayer.setOnCompletionListener(new CicadaExternalPlayer.OnCompletionListener() {
  
              @Override
              public void onCompletion() {
                  nativeOnCompletion(mNativeInstance);
              }
          });
          mExternPlayer.setOnFirstFrameRenderListener(new CicadaExternalPlayer.OnFirstFrameRenderListener() {
  
              @Override
              public void onFirstFrameRender() {
                  nativeOnFirstFrameShow(mNativeInstance);
              }
          });
          mExternPlayer.setOnLoadStatusListener(new CicadaExternalPlayer.OnLoadStatusListener() {
              @Override
              public void onLoadingStart() {
                  nativeOnLoadingStart(mNativeInstance);
              }
  
              @Override
              public void onLoadingProgress(int progress) {
                  nativeOnLoadingProgress(mNativeInstance, progress);
              }
  
              @Override
              public void onLoadingEnd() {
                  nativeOnLoadingEnd(mNativeInstance);
              }
          });
          mExternPlayer.setOnAutoPlayStartListener(new CicadaExternalPlayer.OnAutoPlayStartListener() {
  
              @Override
              public void onAutoPlayStart() {
                  nativeOnAutoPlayStart(mNativeInstance);
              }
          });
          mExternPlayer.setOnSeekStatusListener(new CicadaExternalPlayer.OnSeekStatusListener() {
  
              @Override
              public void onSeekStart(boolean seekInCache) {
                  nativeOnSeeking(mNativeInstance, seekInCache);
              }
  
              @Override
              public void onSeekEnd(boolean seekInCache) {
                  nativeOnSeekEnd(mNativeInstance, seekInCache);
              }
          });
          mExternPlayer.setOnPositionUpdateListener(new CicadaExternalPlayer.OnPositionUpdateListener() {
  
              @Override
              public void onPositionUpdate(long position) {
                  nativeOnPositionUpdate(mNativeInstance, position);
              }
          });
          mExternPlayer.setOnBufferPositionUpdateListener(new CicadaExternalPlayer.OnBufferPositionUpdateListener() {
  
              @Override
              public void onBufferPositionUpdate(long position) {
                  nativeOnBufferPositionUpdate(mNativeInstance, position);
              }
          });
          mExternPlayer.setOnVideoSizeChangedListener(new CicadaExternalPlayer.OnVideoSizeChangedListener() {
              @Override
              public void onVideoSizeChanged(int width, int height) {
                  nativeOnVideoSizeChanged(mNativeInstance, width, height);
              }
          });
          mExternPlayer.setOnStatusChangedListener(new CicadaExternalPlayer.OnStatusChangedListener() {
              @Override
              public void onStatusChanged(int from, int to) {
                  nativeOnStatusChanged(mNativeInstance, from, to);
              }
          });
          mExternPlayer.setOnVideoRenderedListener(new CicadaExternalPlayer.OnVideoRenderedListener() {
  
              @Override
              public void onVideoRendered(long timeMs, long pts) {
                  nativeOnVideoRendered(mNativeInstance, timeMs, pts);
              }
          });
          mExternPlayer.setOnErrorListener(new CicadaExternalPlayer.OnErrorListener() {
  
              @Override
              public void onError(int code, String msg) {
                  nativeOnErrorCallback(mNativeInstance, code, msg);
              }
          });
          mExternPlayer.setOnEventListener(new CicadaExternalPlayer.OnEventListener() {
  
              @Override
              public void onEvent(int code, String msg) {
                  nativeOnEventCallback(mNativeInstance, code, msg);
              }
          });
          mExternPlayer.setOnStreamInfoGetListener(new CicadaExternalPlayer.OnStreamInfoGetListener() {
  
              @Override
              public void OnStreamInfoGet(MediaInfo info) {
                  nativeOnStreamInfoGet(mNativeInstance, info);
              }
          });
          mExternPlayer.setOnStreamSwitchSucListener(new CicadaExternalPlayer.OnStreamSwitchSucListener() {
  
              @Override
              public void onStreamSwitchSuc(CicadaExternalPlayer.StreamType type, TrackInfo trackInfo) {
                  nativeOnStreamSwitchSuc(mNativeInstance, type.ordinal(), trackInfo);
              }
          });
          mExternPlayer.setOnCaptureScreenListener(new CicadaExternalPlayer.OnCaptureScreenListener() {
              @Override
              public void onCaptureScreen(int width, int height, byte[] data) {
                  nativeOnCaptureScreen(mNativeInstance, width, height, data);
              }
          });
          mExternPlayer.setOnSubtitleListener(new CicadaExternalPlayer.OnSubtitleListener() {
              @Override
              public void onSubtitleExtAdded(int trackIndex, String url) {
                  nativeOnSubtitleExtAdd(mNativeInstance, trackIndex, url);
              }
  
              @Override
              public void onSubtitleShow(int trackIndex, long id, String data) {
                  nativeOnSubtitleShow(mNativeInstance, trackIndex, data.getBytes());
              }
  
              @Override
              public void onSubtitleHide(int trackIndex, long id) {
                  nativeOnSubtitleHide(mNativeInstance, trackIndex, null);
              }
          });
          mExternPlayer.setOnDrmCallback(new CicadaExternalPlayer.OnDRMCallback() {
  
              @Override
              public byte[] onRequestProvision(String provisionUrl, byte[] data) {
                  return nativeOnRequestProvision(mNativeInstance ,provisionUrl , data);
              }
  
              @Override
              public byte[] onRequestKey(String licenseUrl, byte[] data) {
                  return nativeOnRequestKey(mNativeInstance , licenseUrl , data);
              }
          });
      }
  
  
      @NativeUsed
      CicadaExternalPlayer.StreamType SwitchStream(int index) {
          if (mExternPlayer == null) {
              return CicadaExternalPlayer.StreamType.ST_TYPE_UNKNOWN;
          }
          return mExternPlayer.switchStream(index);
      }
  
  
      private void setScaleMode(int scaleMode) {
          if (mExternPlayer == null) {
              return;
          }
          CicadaPlayer.ScaleMode targetMode = CicadaPlayer.ScaleMode.SCALE_ASPECT_FIT;
          if (scaleMode == 0) {
              targetMode = CicadaPlayer.ScaleMode.SCALE_ASPECT_FIT;
          } else if (scaleMode == 1) {
              targetMode = CicadaPlayer.ScaleMode.SCALE_ASPECT_FILL;
          } else if (scaleMode == 2) {
              targetMode = CicadaPlayer.ScaleMode.SCALE_TO_FILL;
          }
          mExternPlayer.setScaleMode(targetMode);
      }
  
  
      private void setRotateMode(int mode) {
          if (mExternPlayer == null) {
              return;
          }
          CicadaPlayer.RotateMode rotateMode = CicadaPlayer.RotateMode.ROTATE_0;
          if (mode == 90) {
              rotateMode = CicadaPlayer.RotateMode.ROTATE_90;
          } else if (mode == 180) {
              rotateMode = CicadaPlayer.RotateMode.ROTATE_180;
          } else if (mode == 270) {
              rotateMode = CicadaPlayer.RotateMode.ROTATE_270;
          } else if (mode == 0) {
              rotateMode = CicadaPlayer.RotateMode.ROTATE_0;
          }
          mExternPlayer.setRotateMode(rotateMode);
      }
  
  
      private void setMirrorMode(int mode) {
          if (mExternPlayer == null) {
              return;
          }
          CicadaPlayer.MirrorMode mirrorMode = CicadaPlayer.MirrorMode.MIRROR_MODE_NONE;
          if (mode == 0) {
              mirrorMode = CicadaPlayer.MirrorMode.MIRROR_MODE_NONE;
          } else if (mode == 1) {
              mirrorMode = CicadaPlayer.MirrorMode.MIRROR_MODE_HORIZONTAL;
          } else if (mode == 2) {
              mirrorMode = CicadaPlayer.MirrorMode.MIRROR_MODE_VERTICAL;
          }
          mExternPlayer.setMirrorMode(mirrorMode);
      }
  
      private int getCurrentStreamIndex(int type) {
          if (mExternPlayer == null) {
              return -1;
          }
          CicadaExternalPlayer.StreamType streamType = CicadaExternalPlayer.StreamType.ST_TYPE_UNKNOWN;
          if (type == 0) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_VIDEO;
          } else if (type == 1) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_AUDIO;
          } else if (type == 2) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_SUB;
          }
          return mExternPlayer.getCurrentStreamIndex(streamType);
      }
  
      public Object getCurrentStreamInfo(int type) {
          if (mExternPlayer == null) {
              return null;
          }
  
          CicadaExternalPlayer.StreamType streamType = CicadaExternalPlayer.StreamType.ST_TYPE_UNKNOWN;
          if (type == 0) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_VIDEO;
          } else if (type == 1) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_AUDIO;
          } else if (type == 2) {
              streamType = CicadaExternalPlayer.StreamType.ST_TYPE_SUB;
          }
  
          return mExternPlayer.getCurrentStreamInfo(streamType);
      }
  
      private void setDecoderType(int decoderType) {
          if (mExternPlayer == null) {
              return;
          }
          CicadaExternalPlayer.DecoderType type = CicadaExternalPlayer.DecoderType.DT_SOFTWARE;
          if (decoderType == 0) {
              type = CicadaExternalPlayer.DecoderType.DT_HARDWARE;
          } else if (decoderType == 1) {
              type = CicadaExternalPlayer.DecoderType.DT_HARDWARE;
          }
          mExternPlayer.setDecoderType(type);
      }
  
      private String getPropertyString(CicadaExternalPlayer.PropertyKey key) {
          if (mExternPlayer == null) {
              return null;
          }
          return mExternPlayer.getPropertyString(key);
      }
  
      private long getPropertyInt(CicadaExternalPlayer.PropertyKey key) {
          if (mExternPlayer == null) {
              return 0;
          }
          return mExternPlayer.getPropertyInt(key);
      }
  
      private long getPropertyLong(CicadaExternalPlayer.PropertyKey key) {
          if (mExternPlayer == null) {
              return 0;
          }
          return mExternPlayer.getPropertyLong(key);
      }
  
      private int setOption(String key, String value) {
          if (mExternPlayer == null) {
              return -1;
          }
          return mExternPlayer.setOption(key, value);
      }
  
      private String getOption(String key) {
          if (mExternPlayer == null) {
              return null;
          }
          return mExternPlayer.getOption(key);
      }
  
  
      private int selectExtSubtitle(int index, boolean bSelect) {
          if (mExternPlayer == null) {
              return -1;
          }
          return mExternPlayer.selectExtSubtitle(index, bSelect);
      }
  
  //        //TODO
  //    public int getCurrentStreamMeta(Stream_meta *meta, StreamType type) {
  ////        if (mExternPlayer == null) {
  ////            return;
  ////        }
  ////        mExternPlayer.setTimeout(timeOut);
  //    }
  
  
      private int invokeComponent(String content) {
          if (mExternPlayer == null) {
              return -1;
          }
          return mExternPlayer.invokeComponent(content);
      }
  
      //R: return ,P:param D:default value
      public void callRvPv(String name) {
          if (mExternPlayer == null) {
              return;
          }
  
          if ("Release".equals(name)) {
              mExternPlayer.release();
              mNativeInstance = 0;
              mExternPlayer = null;
          } else if ("Prepare".equals(name)) {
              mExternPlayer.prepare();
          } else if ("Start".equals(name)) {
              mExternPlayer.start();
          } else if ("Pause".equals(name)) {
              mExternPlayer.pause();
          } else if ("CaptureScreen".equals(name)) {
              mExternPlayer.captureScreen();
          } else if ("reLoad".equals(name)) {
              mExternPlayer.reLoad();
          } else if ("RemoveAllCustomHttpHeader".equals(name)) {
              mExternPlayer.removeAllCustomHttpHeader();
          }
      }
  
      public void callRvPf(String name, float value) {
          if (mExternPlayer == null) {
              return;
          }
          if ("SetVolume".equals(name)) {
              mExternPlayer.setVolume(value);
          }
          if ("setSpeed".equals(name)) {
              mExternPlayer.setSpeed(value);
          }
      }
  
      public void callRvPi(String name, int value) {
          if (mExternPlayer == null) {
              return;
          }
          if ("SetVolume".equals(name)) {
              mExternPlayer.setVolume(value);
          } else if ("SetScaleMode".equals(name)) {
              setScaleMode(value);
          } else if ("SetRotateMode".equals(name)) {
              setRotateMode(value);
          } else if ("SetMirrorMode".equals(name)) {
              setMirrorMode(value);
          } else if ("SetTimeout".equals(name)) {
              mExternPlayer.setTimeout(value);
          } else if ("SetDropBufferThreshold".equals(name)) {
              mExternPlayer.setDropBufferThreshold(value);
          } else if ("SetDecoderType".equals(name)) {
              setDecoderType(value);
          }
      }
  
  
      public void callRvPs(String name, String value) {
          if (mExternPlayer == null) {
              return;
          }
          if ("SetDataSource".equals(name)) {
              mExternPlayer.setDataSource(value);
          } else if ("addExtSubtitle".equals(name)) {
              mExternPlayer.addExtSubtitle(value);
          } else if ("AddCustomHttpHeader".equals(name)) {
              mExternPlayer.addCustomHttpHeader(value);
          } else if ("SetUserAgent".equals(name)) {
              mExternPlayer.setUserAgent(value);
          } else if ("SetRefer".equals(name)) {
              mExternPlayer.setRefer(value);
          }
      }
  
      public void callRvPlb(String name, long lv, boolean bv) {
          if (mExternPlayer == null) {
              return;
          }
          if ("SeekTo".equals(name)) {
              mExternPlayer.seekTo(lv, bv);
          } else if ("SetVideoBackgroundColor".equals(name)) {
              mExternPlayer.setVideoBackgroundColor(lv);
          } else if ("Mute".equals(name)) {
              mExternPlayer.mute(bv);
          } else if ("EnterBackGround".equals(name)) {
              mExternPlayer.enterBackGround(bv);
          } else if ("SetLooping".equals(name)) {
              mExternPlayer.setLooping(bv);
          } else if ("SetAutoPlay".equals(name)) {
              mExternPlayer.setAutoPlay(bv);
          } else if("selectExtSubtitle".equals(name)){
              mExternPlayer.selectExtSubtitle((int)lv, bv);
          }
      }
  
      public void callRvPo(String name, Object value) {
          if (mExternPlayer == null) {
              return;
          }
          if ("SetView".equals(name)) {
              mExternPlayer.setSurface((Surface) value);
          }
      }
  
      public Object callRoPi(String name, int value) {
          if (mExternPlayer == null) {
              return null;
          }
  
          if ("GetCurrentStreamInfo".equals(name)) {
              return getCurrentStreamInfo(value);
          }
  
          return null;
      }
  
  
      public boolean callRbPvD(String name, boolean defaultValue) {
          if (mExternPlayer == null) {
              return defaultValue;
          }
  
          if ("IsMute".equals(name)) {
              return mExternPlayer.isMute();
          } else if ("isLooping".equals(name)) {
              return mExternPlayer.isLooping();
          } else if ("IsAutoPlay".equals(name)) {
              return mExternPlayer.isAutoPlay();
          }
  
  
          return defaultValue;
      }
  
      public float callRfPvD(String name, float defaultValue) {
          if (mExternPlayer == null) {
              return defaultValue;
          }
  
          if ("GetVideoRenderFps".equals(name)) {
              return mExternPlayer.getVideoRenderFps();
          } else if ("GetVolume".equals(name)) {
              return mExternPlayer.getVolume();
          } else if ("getSpeed".equals(name)) {
              return mExternPlayer.getSpeed();
          } else if ("GetVideoDecodeFps".equals(name)) {
              return mExternPlayer.getVideoDecodeFps();
          }
  
          return defaultValue;
      }
  
      public int callRiPvD(String name, int defaultValue) {
          if (mExternPlayer == null) {
              return defaultValue;
          }
  
          if ("Stop".equals(name)) {
              mExternPlayer.stop();
              return 0;
          } else if ("GetScaleMode".equals(name)) {
              return mExternPlayer.getScaleMode().getValue();
          } else if ("GetRotateMode".equals(name)) {
              return mExternPlayer.getRotateMode().getValue();
          } else if ("GetMirrorMode".equals(name)) {
              return mExternPlayer.getMirrorMode().getValue();
          } else if ("GetDecoderType".equals(name)) {
              return mExternPlayer.getDecoderType().getValue();
          } else if ("getVideoWidth".equals(name)) {
              return mExternPlayer.getVideoWidth();
          } else if ("getVideoHeight".equals(name)) {
              return mExternPlayer.getVideoHeight();
          } else if ("GetVideoRotation".equals(name)) {
              return mExternPlayer.getVideoRotation();
          }
  
          return defaultValue;
      }
  
      public int callRiPiD(String name, int iv, int defaultValue) {
          if (mExternPlayer == null) {
              return defaultValue;
          }
  
          if ("GetCurrentStreamIndex".equals(name)) {
              return getCurrentStreamIndex(iv);
          } else if ("SwitchStream".equals(name)) {
              return SwitchStream(iv).getValue();
          }
          return defaultValue;
      }
  
  
      public long callRlPvD(String name, long defaultValue) {
          if (mExternPlayer == null) {
              return defaultValue;
          }
  
          if ("GetDuration".equals(name)) {
              return mExternPlayer.getDuration();
          } else if ("GetPlayingPosition".equals(name)) {
              return mExternPlayer.getPlayingPosition();
          } else if ("GetBufferPosition".equals(name)) {
              return mExternPlayer.getBufferPosition();
          } else if ("GetMasterClockPts".equals(name)) {
              return mExternPlayer.getMasterClockPts();
          }
  
          return defaultValue;
      }
  
      //=================================
  
      private native void nativeOnPrepared(long mNativeInstance);
  
      private native void nativeOnLoopingStart(long mNativeInstance);
  
      private native void nativeOnCompletion(long mNativeInstance);
  
      private native void nativeOnFirstFrameShow(long mNativeInstance);
  
      private native void nativeOnLoadingStart(long mNativeInstance);
  
      private native void nativeOnLoadingEnd(long mNativeInstance);
  
      private native void nativeOnAutoPlayStart(long mNativeInstance);
  
      private native void nativeOnSeeking(long mNativeInstance, boolean seekInCache);
  
      private native void nativeOnSeekEnd(long mNativeInstance, boolean seekInCache);
  
      private native void nativeOnPositionUpdate(long mNativeInstance, long position);
  
      private native void nativeOnBufferPositionUpdate(long mNativeInstance, long bufferPosition);
  
      private native void nativeOnLoadingProgress(long mNativeInstance, long progress);
  
      private native void nativeOnVideoSizeChanged(long mNativeInstance, int width, int height);
  
      private native void nativeOnStatusChanged(long mNativeInstance, int from, int to);
  
      private native void nativeOnVideoRendered(long mNativeInstance, long timeMs, long pts);
  
      private native void nativeOnErrorCallback(long mNativeInstance, long code, String msg);
  
      private native void nativeOnEventCallback(long mNativeInstance, long code, String msg);
  
      private native void nativeOnStreamInfoGet(long mNativeInstance, MediaInfo info);
  
      private native void nativeOnStreamSwitchSuc(long mNativeInstance, int type, TrackInfo info);
  
      private native void nativeOnCaptureScreen(long mNativeInstance, int width, int height, byte[] datas);
  
      private native void nativeOnSubtitleHide(long mNativeInstance, long index, byte[] content);
  
      private native void nativeOnSubtitleShow(long mNativeInstance, long index, byte[] content);
  
      private native void nativeOnSubtitleExtAdd(long mNativeInstance, long index, String url);
  
      private native byte[] nativeOnRequestProvision(long mNativeInstance , String provisionUrl , byte[] data);
  
      private native byte[] nativeOnRequestKey(long mNativeInstance , String licenseUrl , byte[] data);
  }
  