// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/android/shared/media_capabilities_cache.h"

#include <utility>

#include "starboard/android/shared/jni_utils.h"
#include "starboard/android/shared/media_common.h"
#include "starboard/common/log.h"
#include "starboard/once.h"
#include "starboard/shared/starboard/media/key_system_supportability_cache.h"
#include "starboard/shared/starboard/media/mime_supportability_cache.h"
#include "starboard/thread.h"

namespace starboard {
namespace android {
namespace shared {
namespace {

using ::starboard::shared::starboard::media::KeySystemSupportabilityCache;
using ::starboard::shared::starboard::media::MimeSupportabilityCache;

// https://developer.android.com/reference/android/view/Display.HdrCapabilities.html#HDR_TYPE_HDR10
const jint HDR_TYPE_DOLBY_VISION = 1;
const jint HDR_TYPE_HDR10 = 2;
const jint HDR_TYPE_HLG = 3;
const jint HDR_TYPE_HDR10_PLUS = 4;

const char SECURE_DECODER_SUFFIX[] = ".secure";

// Constants for output types from
// https://developer.android.com/reference/android/media/AudioDeviceInfo.
constexpr int TYPE_AUX_LINE = 19;
constexpr int TYPE_BLE_BROADCAST = 30;
constexpr int TYPE_BLE_HEADSET = 26;
constexpr int TYPE_BLE_SPEAKER = 27;
constexpr int TYPE_BLUETOOTH_A2DP = 8;
constexpr int TYPE_BLUETOOTH_SCO = 7;
constexpr int TYPE_BUILTIN_EARPIECE = 1;
constexpr int TYPE_BUILTIN_MIC = 15;
constexpr int TYPE_BUILTIN_SPEAKER = 2;
constexpr int TYPE_BUILTIN_SPEAKER_SAFE = 24;
constexpr int TYPE_BUS = 21;
constexpr int TYPE_DOCK = 13;
constexpr int TYPE_DOCK_ANALOG = 31;
constexpr int TYPE_FM = 14;
constexpr int TYPE_FM_TUNER = 16;
constexpr int TYPE_HDMI = 9;
constexpr int TYPE_HDMI_ARC = 10;
constexpr int TYPE_HDMI_EARC = 29;
constexpr int TYPE_HEARING_AID = 23;
constexpr int TYPE_IP = 20;
constexpr int TYPE_LINE_ANALOG = 5;
constexpr int TYPE_LINE_DIGITAL = 6;
constexpr int TYPE_REMOTE_SUBMIX = 25;
constexpr int TYPE_TELEPHONY = 18;
constexpr int TYPE_TV_TUNER = 17;
constexpr int TYPE_UNKNOWN = 0;
constexpr int TYPE_USB_ACCESSORY = 12;
constexpr int TYPE_USB_DEVICE = 11;
constexpr int TYPE_USB_HEADSET = 22;
constexpr int TYPE_WIRED_HEADPHONES = 4;
constexpr int TYPE_WIRED_HEADSET = 3;

#if SB_API_VERSION >= 15
SbMediaAudioConnector GetConnectorFromAndroidOutputType(
    int android_output_device_type) {
  switch (android_output_device_type) {
    case TYPE_AUX_LINE:
      return kSbMediaAudioConnectorAnalog;
    case TYPE_BLE_BROADCAST:
      return kSbMediaAudioConnectorBluetooth;
    case TYPE_BLE_HEADSET:
      return kSbMediaAudioConnectorBluetooth;
    case TYPE_BLE_SPEAKER:
      return kSbMediaAudioConnectorBluetooth;
    case TYPE_BLUETOOTH_A2DP:
      return kSbMediaAudioConnectorBluetooth;
    case TYPE_BLUETOOTH_SCO:
      return kSbMediaAudioConnectorBluetooth;
    case TYPE_BUILTIN_EARPIECE:
      return kSbMediaAudioConnectorBuiltIn;
    case TYPE_BUILTIN_MIC:
      return kSbMediaAudioConnectorBuiltIn;
    case TYPE_BUILTIN_SPEAKER:
      return kSbMediaAudioConnectorBuiltIn;
    case TYPE_BUILTIN_SPEAKER_SAFE:
      return kSbMediaAudioConnectorBuiltIn;
    case TYPE_BUS:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_DOCK:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_DOCK_ANALOG:
      return kSbMediaAudioConnectorAnalog;
    case TYPE_FM:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_FM_TUNER:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_HDMI:
      return kSbMediaAudioConnectorHdmi;
    case TYPE_HDMI_ARC:
      return kSbMediaAudioConnectorHdmi;
    case TYPE_HDMI_EARC:
      return kSbMediaAudioConnectorHdmi;
    case TYPE_HEARING_AID:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_IP:
      return kSbMediaAudioConnectorRemoteWired;
    case TYPE_LINE_ANALOG:
      return kSbMediaAudioConnectorAnalog;
    case TYPE_LINE_DIGITAL:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_REMOTE_SUBMIX:
      return kSbMediaAudioConnectorRemoteOther;
    case TYPE_TELEPHONY:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_TV_TUNER:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_UNKNOWN:
      return kSbMediaAudioConnectorUnknown;
    case TYPE_USB_ACCESSORY:
      return kSbMediaAudioConnectorUsb;
    case TYPE_USB_DEVICE:
      return kSbMediaAudioConnectorUsb;
    case TYPE_USB_HEADSET:
      return kSbMediaAudioConnectorUsb;
    case TYPE_WIRED_HEADPHONES:
      return kSbMediaAudioConnectorAnalog;
    case TYPE_WIRED_HEADSET:
      return kSbMediaAudioConnectorAnalog;
  }

  SB_LOG(WARNING) << "Encountered unknown audio output device type "
                  << android_output_device_type;
  return kSbMediaAudioConnectorUnknown;
}
#endif  // SB_API_VERSION >= 15

bool EndsWith(const std::string& str, const std::string& suffix) {
  if (str.size() < suffix.size()) {
    return false;
  }
  return strcmp(str.c_str() + (str.size() - suffix.size()), suffix.c_str()) ==
         0;
}

Range ConvertJavaRangeToRange(JniEnvExt* env, jobject j_range) {
  ScopedLocalJavaRef<jobject> j_upper_comparable(env->CallObjectMethodOrAbort(
      j_range, "getUpper", "()Ljava/lang/Comparable;"));
  jint j_upper_int =
      env->CallIntMethodOrAbort(j_upper_comparable.Get(), "intValue", "()I");

  ScopedLocalJavaRef<jobject> j_lower_comparable(env->CallObjectMethodOrAbort(
      j_range, "getLower", "()Ljava/lang/Comparable;"));
  jint j_lower_int =
      env->CallIntMethodOrAbort(j_lower_comparable.Get(), "intValue", "()I");
  return Range(j_lower_int, j_upper_int);
}

void ConvertStringToLowerCase(std::string* str) {
  for (int i = 0; i < str->length(); i++) {
    (*str)[i] = std::tolower((*str)[i]);
  }
}

bool GetIsWidevineSupported() {
  return JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
             "dev/cobalt/media/MediaDrmBridge",
             "isWidevineCryptoSchemeSupported", "()Z") == JNI_TRUE;
}

bool GetIsCbcsSupported() {
  return JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
             "dev/cobalt/media/MediaDrmBridge", "isCbcsSchemeSupported",
             "()Z") == JNI_TRUE;
}

std::set<SbMediaTransferId> GetSupportedHdrTypes() {
  std::set<SbMediaTransferId> supported_transfer_ids;

  JniEnvExt* env = JniEnvExt::Get();
  jintArray j_supported_hdr_types = static_cast<jintArray>(
      env->CallStarboardObjectMethodOrAbort("getSupportedHdrTypes", "()[I"));

  if (!j_supported_hdr_types) {
    // Failed to get supported hdr types.
    SB_LOG(ERROR) << "Failed to load supported hdr types.";
    return std::set<SbMediaTransferId>();
  }

  jsize length = env->GetArrayLength(j_supported_hdr_types);
  jint* numbers = env->GetIntArrayElements(j_supported_hdr_types, 0);
  for (int i = 0; i < length; i++) {
    switch (numbers[i]) {
      case HDR_TYPE_DOLBY_VISION:
        continue;
      case HDR_TYPE_HDR10:
        supported_transfer_ids.insert(kSbMediaTransferIdSmpteSt2084);
        continue;
      case HDR_TYPE_HLG:
        supported_transfer_ids.insert(kSbMediaTransferIdAribStdB67);
        continue;
      case HDR_TYPE_HDR10_PLUS:
        continue;
    }
  }
  env->ReleaseIntArrayElements(j_supported_hdr_types, numbers, 0);

  return supported_transfer_ids;
}

bool GetIsPassthroughSupported(SbMediaAudioCodec codec) {
  SbMediaAudioCodingType coding_type;
  switch (codec) {
    case kSbMediaAudioCodecAc3:
      coding_type = kSbMediaAudioCodingTypeAc3;
      break;
    case kSbMediaAudioCodecEac3:
      coding_type = kSbMediaAudioCodingTypeDolbyDigitalPlus;
      break;
    default:
      return false;
  }
  int encoding = GetAudioFormatSampleType(coding_type);
  JniEnvExt* env = JniEnvExt::Get();
  ScopedLocalJavaRef<jobject> j_audio_output_manager(
      env->CallStarboardObjectMethodOrAbort(
          "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
  return env->CallBooleanMethodOrAbort(j_audio_output_manager.Get(),
                                       "hasPassthroughSupportFor", "(I)Z",
                                       encoding) == JNI_TRUE;
}

bool GetAudioConfiguration(int index,
                           SbMediaAudioConfiguration* configuration) {
  *configuration = {};

  JniEnvExt* env = JniEnvExt::Get();
  ScopedLocalJavaRef<jobject> j_audio_output_manager(
      env->CallStarboardObjectMethodOrAbort(
          "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
  ScopedLocalJavaRef<jobject> j_output_device_info(env->NewObjectOrAbort(
      "dev/cobalt/media/AudioOutputManager$OutputDeviceInfo", "()V"));

  bool succeeded = env->CallBooleanMethodOrAbort(
      j_audio_output_manager.Get(), "getOutputDeviceInfo",
      "(ILdev/cobalt/media/AudioOutputManager$OutputDeviceInfo;)Z", index,
      j_output_device_info.Get());

  if (!succeeded) {
    SB_LOG(WARNING)
        << "Call to AudioOutputManager.getOutputDeviceInfo() failed.";
    return false;
  }

  auto call_int_method = [env, &j_output_device_info](const char* name) {
    return env->CallIntMethodOrAbort(j_output_device_info.Get(), name, "()I");
  };

#if SB_API_VERSION >= 15
  configuration->connector =
      GetConnectorFromAndroidOutputType(call_int_method("getType"));
#else   // SB_API_VERSION >= 15
  configuration->connector = kSbMediaAudioConnectorHdmi;
#endif  // SB_API_VERSION >= 15
  configuration->latency = 0;
  configuration->coding_type = kSbMediaAudioCodingTypePcm;
  configuration->number_of_channels = call_int_method("getChannels");

  if (configuration->connector != kSbMediaAudioConnectorHdmi) {
    configuration->number_of_channels = 2;
  }

  return true;
}

}  // namespace

CodecCapability::CodecCapability(JniEnvExt* env, jobject j_codec_info) {
  SB_DCHECK(env);
  SB_DCHECK(j_codec_info);

  ScopedLocalJavaRef<jstring> j_decoder_name(
      env->GetStringFieldOrAbort(j_codec_info, "decoderName"));
  name_ = env->GetStringStandardUTFOrAbort(j_decoder_name.Get());
  is_secure_required_ =
      env->CallBooleanMethodOrAbort(j_codec_info, "isSecureRequired", "()Z") ==
      JNI_TRUE;
  is_secure_supported_ =
      env->CallBooleanMethodOrAbort(j_codec_info, "isSecureSupported", "()Z") ==
      JNI_TRUE;
  is_tunnel_mode_required_ =
      env->CallBooleanMethodOrAbort(j_codec_info, "isTunnelModeRequired",
                                    "()Z") == JNI_TRUE;
  is_tunnel_mode_supported_ =
      env->CallBooleanMethodOrAbort(j_codec_info, "isTunnelModeSupported",
                                    "()Z") == JNI_TRUE;
}

AudioCodecCapability::AudioCodecCapability(JniEnvExt* env,
                                           jobject j_codec_info,
                                           jobject j_audio_capabilities)
    : CodecCapability(env, j_codec_info) {
  SB_DCHECK(env);
  SB_DCHECK(j_codec_info);
  SB_DCHECK(j_audio_capabilities);

  ScopedLocalJavaRef<jobject> j_bitrate_range(env->CallObjectMethodOrAbort(
      j_audio_capabilities, "getBitrateRange", "()Landroid/util/Range;"));
  supported_bitrates_ = ConvertJavaRangeToRange(env, j_bitrate_range.Get());

  // Overwrite the lower bound to 0.
  supported_bitrates_.minimum = 0;
}

bool AudioCodecCapability::IsBitrateSupported(int bitrate) const {
  return supported_bitrates_.Contains(bitrate);
}

VideoCodecCapability::VideoCodecCapability(JniEnvExt* env,
                                           jobject j_codec_info,
                                           jobject j_video_capabilities)
    : CodecCapability(env, j_codec_info) {
  SB_DCHECK(env);
  SB_DCHECK(j_codec_info);
  SB_DCHECK(j_video_capabilities);

  is_software_decoder_ = env->CallBooleanMethodOrAbort(
                             j_codec_info, "isSoftware", "()Z") == JNI_TRUE;

  is_hdr_capable_ = env->CallBooleanMethodOrAbort(j_codec_info, "isHdrCapable",
                                                  "()Z") == JNI_TRUE;

  j_video_capabilities_ = env->NewGlobalRef(j_video_capabilities);

  ScopedLocalJavaRef<jobject> j_width_range(env->CallObjectMethodOrAbort(
      j_video_capabilities_, "getSupportedWidths", "()Landroid/util/Range;"));
  supported_widths_ = ConvertJavaRangeToRange(env, j_width_range.Get());

  ScopedLocalJavaRef<jobject> j_height_range(env->CallObjectMethodOrAbort(
      j_video_capabilities_, "getSupportedHeights", "()Landroid/util/Range;"));
  supported_heights_ = ConvertJavaRangeToRange(env, j_height_range.Get());

  ScopedLocalJavaRef<jobject> j_bitrate_range(env->CallObjectMethodOrAbort(
      j_video_capabilities_, "getBitrateRange", "()Landroid/util/Range;"));
  supported_bitrates_ = ConvertJavaRangeToRange(env, j_bitrate_range.Get());

  ScopedLocalJavaRef<jobject> j_frame_rate_range(env->CallObjectMethodOrAbort(
      j_video_capabilities_, "getSupportedFrameRates",
      "()Landroid/util/Range;"));
  supported_frame_rates_ =
      ConvertJavaRangeToRange(env, j_frame_rate_range.Get());
}

VideoCodecCapability::~VideoCodecCapability() {
  JniEnvExt* env = JniEnvExt::Get();
  env->DeleteGlobalRef(j_video_capabilities_);
}

bool VideoCodecCapability::IsBitrateSupported(int bitrate) const {
  return supported_bitrates_.Contains(bitrate);
}

bool VideoCodecCapability::AreResolutionAndRateSupported(int frame_width,
                                                         int frame_height,
                                                         int fps) {
  if (frame_width != 0 && frame_height != 0 && fps != 0) {
    return JniEnvExt::Get()->CallBooleanMethodOrAbort(
               j_video_capabilities_, "areSizeAndRateSupported", "(IID)Z",
               frame_width, frame_height,
               static_cast<jdouble>(fps)) == JNI_TRUE;
  } else if (frame_width != 0 && frame_height != 0) {
    return JniEnvExt::Get()->CallBooleanMethodOrAbort(
               j_video_capabilities_, "isSizeSupported", "(II)Z", frame_width,
               frame_height) == JNI_TRUE;
  }
  if (frame_width != 0 && !supported_widths_.Contains(frame_width)) {
    return false;
  }
  if (frame_height != 0 && !supported_heights_.Contains(frame_height)) {
    return false;
  }
  if (fps != 0 && !supported_frame_rates_.Contains(fps)) {
    return false;
  }
  return true;
}

// static
SB_ONCE_INITIALIZE_FUNCTION(MediaCapabilitiesCache,
                            MediaCapabilitiesCache::GetInstance);

bool MediaCapabilitiesCache::IsWidevineSupported() {
  if (!is_enabled_) {
    return GetIsWidevineSupported();
  }
  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();
  return is_widevine_supported_;
}

bool MediaCapabilitiesCache::IsCbcsSchemeSupported() {
  if (!is_enabled_) {
    return GetIsCbcsSupported();
  }
  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();
  return is_cbcs_supported_;
}

bool MediaCapabilitiesCache::IsHDRTransferCharacteristicsSupported(
    SbMediaTransferId transfer_id) {
  if (!is_enabled_) {
    std::set<SbMediaTransferId> supported_transfer_ids = GetSupportedHdrTypes();
    return supported_transfer_ids.find(transfer_id) !=
           supported_transfer_ids.end();
  }
  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();
  return supported_transfer_ids_.find(transfer_id) !=
         supported_transfer_ids_.end();
}

bool MediaCapabilitiesCache::IsPassthroughSupported(SbMediaAudioCodec codec) {
  if (!is_enabled_) {
    return GetIsPassthroughSupported(codec);
  }
  // IsPassthroughSupported() caches the results of previous quiries, and does
  // not rely on LazyInitialize(), which is different from other functions.
  ScopedLock scoped_lock(mutex_);
  auto iter = passthrough_supportabilities_.find(codec);
  if (iter != passthrough_supportabilities_.end()) {
    return iter->second;
  }
  bool supported = GetIsPassthroughSupported(codec);
  passthrough_supportabilities_[codec] = supported;
  return supported;
}

bool MediaCapabilitiesCache::GetAudioConfiguration(
    int index,
    SbMediaAudioConfiguration* configuration) {
  SB_DCHECK(index >= 0);
  if (!is_enabled_) {
    return ::starboard::android::shared::GetAudioConfiguration(index,
                                                               configuration);
  }

  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();
  if (index < audio_configurations_.size()) {
    *configuration = audio_configurations_[index];
    return true;
  }
  return false;
}

bool MediaCapabilitiesCache::HasAudioDecoderFor(const std::string& mime_type,
                                                int bitrate) {
  return !FindAudioDecoder(mime_type, bitrate).empty();
}

bool MediaCapabilitiesCache::HasVideoDecoderFor(const std::string& mime_type,
                                                bool must_support_secure,
                                                bool must_support_hdr,
                                                bool must_support_tunnel_mode,
                                                int frame_width,
                                                int frame_height,
                                                int bitrate,
                                                int fps) {
  return !FindVideoDecoder(mime_type, must_support_secure, must_support_hdr,
                           false, must_support_tunnel_mode, frame_width,
                           frame_height, bitrate, fps)
              .empty();
}

std::string MediaCapabilitiesCache::FindAudioDecoder(
    const std::string& mime_type,
    int bitrate) {
  if (!is_enabled_) {
    JniEnvExt* env = JniEnvExt::Get();
    ScopedLocalJavaRef<jstring> j_mime(
        env->NewStringStandardUTFOrAbort(mime_type.c_str()));
    jobject j_decoder_name = env->CallStaticObjectMethodOrAbort(
        "dev/cobalt/media/MediaCodecUtil", "findAudioDecoder",
        "(Ljava/lang/String;I)Ljava/lang/String;", j_mime.Get(), bitrate);
    return env->GetStringStandardUTFOrAbort(
        static_cast<jstring>(j_decoder_name));
  }

  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();

  for (auto& audio_capability : audio_codec_capabilities_map_[mime_type]) {
    // Reject if bitrate is not supported.
    if (!audio_capability->IsBitrateSupported(bitrate)) {
      continue;
    }
    return audio_capability->name();
  }

  return "";
}

std::string MediaCapabilitiesCache::FindVideoDecoder(
    const std::string& mime_type,
    bool must_support_secure,
    bool must_support_hdr,
    bool require_software_codec,
    bool must_support_tunnel_mode,
    int frame_width,
    int frame_height,
    int bitrate,
    int fps) {
  if (!is_enabled_) {
    JniEnvExt* env = JniEnvExt::Get();
    ScopedLocalJavaRef<jstring> j_mime(
        env->NewStringStandardUTFOrAbort(mime_type.c_str()));
    jobject j_decoder_name = env->CallStaticObjectMethodOrAbort(
        "dev/cobalt/media/MediaCodecUtil", "findVideoDecoder",
        "(Ljava/lang/String;ZZZZIIIII)Ljava/lang/String;", j_mime.Get(),
        must_support_secure, must_support_hdr,
        false,                        /* mustSupportSoftwareCodec */
        must_support_tunnel_mode, -1, /* decoderCacheTtlMs */
        frame_width, frame_height, bitrate, fps);
    return env->GetStringStandardUTFOrAbort(
        static_cast<jstring>(j_decoder_name));
  }

  ScopedLock scoped_lock(mutex_);
  UpdateMediaCapabilities_Locked();

  for (auto& video_capability : video_codec_capabilities_map_[mime_type]) {
    // Reject if secure decoder is required but codec doesn't support it.
    if (must_support_secure && !video_capability->is_secure_supported()) {
      continue;
    }
    // Reject if non secure decoder is required but codec doesn't support it.
    if (!must_support_secure && video_capability->is_secure_required()) {
      continue;
    }
    // Reject if tunnel mode is required but codec doesn't support it.
    if (must_support_tunnel_mode &&
        !video_capability->is_tunnel_mode_supported()) {
      continue;
    }
    // Reject if non tunnel mode is required but codec doesn't support it.
    if (!must_support_tunnel_mode &&
        video_capability->is_tunnel_mode_required()) {
      continue;
    }
    // Reject if software codec is required but codec is not.
    if (require_software_codec && !video_capability->is_software_decoder()) {
      continue;
    }
    // Reject if hdr is required but codec doesn't support it.
    if (must_support_hdr && !video_capability->is_hdr_capable()) {
      continue;
    }

    // Reject if resolution or frame rate is not supported.
    if (!video_capability->AreResolutionAndRateSupported(frame_width,
                                                         frame_height, fps)) {
      continue;
    }

    // Reject if bitrate is not supported.
    if (bitrate != 0 && !video_capability->IsBitrateSupported(bitrate)) {
      continue;
    }

    // Append ".secure" for secure decoder if not represents.
    if (must_support_secure &&
        !EndsWith(video_capability->name(), SECURE_DECODER_SUFFIX)) {
      return video_capability->name() + SECURE_DECODER_SUFFIX;
    }
    return video_capability->name();
  }

  return "";
}

MediaCapabilitiesCache::MediaCapabilitiesCache() {
  // Enable mime and key system caches.
  MimeSupportabilityCache::GetInstance()->SetCacheEnabled(true);
  KeySystemSupportabilityCache::GetInstance()->SetCacheEnabled(true);
}

void MediaCapabilitiesCache::UpdateMediaCapabilities_Locked() {
  mutex_.DCheckAcquired();
  if (capabilities_is_dirty_.exchange(false)) {
    // We use a different cache strategy (load and cache) for passthrough
    // supportabilities, so we only clear |passthrough_supportabilities_| here.
    passthrough_supportabilities_.clear();

    audio_codec_capabilities_map_.clear();
    video_codec_capabilities_map_.clear();
    audio_configurations_.clear();
    is_widevine_supported_ = GetIsWidevineSupported();
    is_cbcs_supported_ = GetIsCbcsSupported();
    supported_transfer_ids_ = GetSupportedHdrTypes();
    LoadCodecInfos_Locked();
    LoadAudioConfigurations_Locked();
  }
}

void MediaCapabilitiesCache::LoadCodecInfos_Locked() {
  SB_DCHECK(audio_codec_capabilities_map_.empty());
  SB_DCHECK(video_codec_capabilities_map_.empty());
  mutex_.DCheckAcquired();

  JniEnvExt* env = JniEnvExt::Get();
  ScopedLocalJavaRef<jobjectArray> j_codec_infos(
      static_cast<jobjectArray>(env->CallStaticObjectMethodOrAbort(
          "dev/cobalt/media/MediaCodecUtil", "getAllCodecCapabilityInfos",
          "()[Ldev/cobalt/media/MediaCodecUtil$CodecCapabilityInfo;")));
  jsize length = env->GetArrayLength(j_codec_infos.Get());
  // Note: Codec infos are sorted by the framework such that the best
  // decoders come first.
  // This order is maintained in the cache.
  for (int i = 0; i < length; i++) {
    ScopedLocalJavaRef<jobject> j_codec_info(
        env->GetObjectArrayElementOrAbort(j_codec_infos.Get(), i));

    ScopedLocalJavaRef<jstring> j_mime_type(
        env->GetStringFieldOrAbort(j_codec_info.Get(), "mimeType"));
    std::string mime_type = env->GetStringStandardUTFOrAbort(j_mime_type.Get());
    // Convert the mime type to lower case.
    ConvertStringToLowerCase(&mime_type);

    ScopedLocalJavaRef<jobject> j_audio_capabilities(env->GetObjectFieldOrAbort(
        j_codec_info.Get(), "audioCapabilities",
        "Landroid/media/MediaCodecInfo$AudioCapabilities;"));
    if (j_audio_capabilities) {
      // Found an audio decoder.
      std::unique_ptr<AudioCodecCapability> audio_codec_capabilities(
          new AudioCodecCapability(env, j_codec_info.Get(),
                                   j_audio_capabilities.Get()));
      audio_codec_capabilities_map_[mime_type].push_back(
          std::move(audio_codec_capabilities));
      continue;
    }
    ScopedLocalJavaRef<jobject> j_video_capabilities(env->GetObjectFieldOrAbort(
        j_codec_info.Get(), "videoCapabilities",
        "Landroid/media/MediaCodecInfo$VideoCapabilities;"));
    if (j_video_capabilities) {
      // Found a video decoder.
      std::unique_ptr<VideoCodecCapability> video_codec_capabilities(
          new VideoCodecCapability(env, j_codec_info.Get(),
                                   j_video_capabilities.Get()));
      video_codec_capabilities_map_[mime_type].push_back(
          std::move(video_codec_capabilities));
    }
  }
}

void MediaCapabilitiesCache::LoadAudioConfigurations_Locked() {
  SB_DCHECK(audio_configurations_.empty());
  mutex_.DCheckAcquired();

  // SbPlayerBridge::GetAudioConfigurations() reads up to 32 configurations. The
  // limit here is to avoid infinite loop and also match
  // SbPlayerBridge::GetAudioConfigurations().
  const int kMaxAudioConfigurations = 32;
  SbMediaAudioConfiguration configuration;
  while (audio_configurations_.size() < kMaxAudioConfigurations &&
         ::starboard::android::shared::GetAudioConfiguration(
             audio_configurations_.size(), &configuration)) {
    audio_configurations_.push_back(configuration);
  }
}

extern "C" SB_EXPORT_PLATFORM void
Java_dev_cobalt_util_DisplayUtil_nativeOnDisplayChanged() {
  // Display device change could change hdr capabilities.
  MediaCapabilitiesCache::GetInstance()->ClearCache();
  MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();
}

extern "C" SB_EXPORT_PLATFORM void
Java_dev_cobalt_media_AudioOutputManager_nativeOnAudioDeviceChanged() {
  // Audio output device change could change passthrough decoder capabilities,
  // so we have to reload codec capabilities.
  MediaCapabilitiesCache::GetInstance()->ClearCache();
  MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();
}

}  // namespace shared
}  // namespace android
}  // namespace starboard
