void
BluetoothGattManager::Connect(const nsAString& aAppUuid,
                              const nsAString& aDeviceAddr,
                              BluetoothReplyRunnable* aRunnable)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aRunnable);

  ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);

  size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
  if (index == sClients->NoIndex) {
    index = sClients->Length();
    sClients->AppendElement(new BluetoothGattClient(aAppUuid, aDeviceAddr));
  }

  nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
  client->mConnectRunnable = aRunnable;

  if (client->mClientIf > 0) {
    sBluetoothGattClientInterface->Connect(client->mClientIf,
                                           aDeviceAddr,
                                           true, // direct connect
                                           new ConnectResultHandler(client));
  } else {
    BluetoothUuid uuid;
    StringToUuid(NS_ConvertUTF16toUTF8(aAppUuid).get(), uuid);

    // connect will be proceeded after client registered
    sBluetoothGattClientInterface->RegisterClient(
      uuid, new RegisterClientResultHandler(client));
  }
}
void
TelemetryIPCAccumulator::RecordChildEvent(const mozilla::TimeStamp& timestamp,
                                          const nsACString& category,
                                          const nsACString& method,
                                          const nsACString& object,
                                          const mozilla::Maybe<nsCString>& value,
                                          const nsTArray<mozilla::Telemetry::EventExtraEntry>& extra)
{
  StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);

  if (!gChildEvents) {
    gChildEvents = new nsTArray<ChildEventData>();
  }

  if (gChildEvents->Length() >=
      kWaterMarkDiscardFactor * kEventsArrayHighWaterMark) {
    gDiscardedData.mDiscardedChildEvents++;
    return;
  }

  if (gChildEvents->Length() == kEventsArrayHighWaterMark) {
    DispatchIPCTimerFired();
  }

  // Store the event.
  gChildEvents->AppendElement(ChildEventData{timestamp, nsCString(category),
                                             nsCString(method), nsCString(object),
                                             value,
                                             nsTArray<mozilla::Telemetry::EventExtraEntry>(extra)});
  ArmIPCTimer(locker);
}
/* static */
void AudioNotificationReceiver::Register(
    DeviceChangeListener* aDeviceChangeListener) {
  MOZ_ASSERT(XRE_IsContentProcess());

  StaticMutexAutoLock lock(sMutex);
  if (!sSubscribers) {
    sSubscribers = new nsTArray<DeviceChangeListener*>();
  }
  sSubscribers->AppendElement(aDeviceChangeListener);

  ANR_LOG("The DeviceChangeListener: %p is registered successfully.",
          aDeviceChangeListener);
}
void
TelemetryIPCAccumulator::AccumulateChildKeyedHistogram(mozilla::Telemetry::HistogramID aId,
                                                       const nsCString& aKey, uint32_t aSample)
{
  StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);
  if (!gKeyedHistogramAccumulations) {
    gKeyedHistogramAccumulations = new nsTArray<KeyedHistogramAccumulation>();
  }
  if (gKeyedHistogramAccumulations->Length() >=
      kWaterMarkDiscardFactor * kHistogramAccumulationsArrayHighWaterMark) {
    gDiscardedData.mDiscardedKeyedHistogramAccumulations++;
    return;
  }
  if (gKeyedHistogramAccumulations->Length() == kHistogramAccumulationsArrayHighWaterMark) {
    DispatchIPCTimerFired();
  }
  gKeyedHistogramAccumulations->AppendElement(KeyedHistogramAccumulation{aId, aSample, aKey});
  ArmIPCTimer(locker);
}
void
TelemetryIPCAccumulator::RecordChildScalarAction(uint32_t aId, bool aDynamic,
                                                 ScalarActionType aAction, const ScalarVariant& aValue)
{
  StaticMutexAutoLock locker(gTelemetryIPCAccumulatorMutex);
  // Make sure to have the storage.
  if (!gChildScalarsActions) {
    gChildScalarsActions = new nsTArray<ScalarAction>();
  }
  if (gChildScalarsActions->Length() >=
      kWaterMarkDiscardFactor * kScalarActionsArrayHighWaterMark) {
    gDiscardedData.mDiscardedScalarActions++;
    return;
  }
  if (gChildScalarsActions->Length() == kScalarActionsArrayHighWaterMark) {
    DispatchIPCTimerFired();
  }
  // Store the action.
  gChildScalarsActions->AppendElement(ScalarAction{aId, aDynamic, aAction, Some(aValue)});
  ArmIPCTimer(locker);
}
static const nsTArray<KeySystemConfig>&
GetSupportedKeySystems()
{
  if (!sKeySystemConfigs) {
    sKeySystemConfigs = new nsTArray<KeySystemConfig>();
    ClearOnShutdown(&sKeySystemConfigs);

    {
      KeySystemConfig clearkey;
      clearkey.mKeySystem = NS_ConvertUTF8toUTF16(kEMEKeySystemClearkey);
      clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("cenc"));
      clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("keyids"));
      clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("webm"));
      clearkey.mPersistentState = KeySystemFeatureSupport::Requestable;
      clearkey.mDistinctiveIdentifier = KeySystemFeatureSupport::Prohibited;
      clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Temporary);
      clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Persistent_license);
#if defined(XP_WIN)
      // Clearkey CDM uses WMF decoders on Windows.
      if (WMFDecoderModule::HasAAC()) {
        clearkey.mMP4.SetCanDecryptAndDecode(GMP_CODEC_AAC);
      } else {
        clearkey.mMP4.SetCanDecrypt(GMP_CODEC_AAC);
      }
      if (WMFDecoderModule::HasH264()) {
        clearkey.mMP4.SetCanDecryptAndDecode(GMP_CODEC_H264);
      } else {
        clearkey.mMP4.SetCanDecrypt(GMP_CODEC_H264);
      }
#else
      clearkey.mMP4.SetCanDecrypt(GMP_CODEC_AAC);
      clearkey.mMP4.SetCanDecrypt(GMP_CODEC_H264);
#endif
      clearkey.mWebM.SetCanDecrypt(GMP_CODEC_VORBIS);
      clearkey.mWebM.SetCanDecrypt(GMP_CODEC_OPUS);
      clearkey.mWebM.SetCanDecrypt(GMP_CODEC_VP8);
      clearkey.mWebM.SetCanDecrypt(GMP_CODEC_VP9);
      sKeySystemConfigs->AppendElement(Move(clearkey));
    }
    {
      KeySystemConfig widevine;
      widevine.mKeySystem = NS_ConvertUTF8toUTF16(kEMEKeySystemWidevine);
      widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("cenc"));
      widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("keyids"));
      widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("webm"));
      widevine.mPersistentState = KeySystemFeatureSupport::Requestable;
      widevine.mDistinctiveIdentifier = KeySystemFeatureSupport::Prohibited;
      widevine.mSessionTypes.AppendElement(MediaKeySessionType::Temporary);
      widevine.mAudioRobustness.AppendElement(NS_LITERAL_STRING("SW_SECURE_CRYPTO"));
      widevine.mVideoRobustness.AppendElement(NS_LITERAL_STRING("SW_SECURE_DECODE"));
#if defined(XP_WIN)
      // Widevine CDM doesn't include an AAC decoder. So if WMF can't
      // decode AAC, and a codec wasn't specified, be conservative
      // and reject the MediaKeys request, since our policy is to prevent
      //  the Adobe GMP's unencrypted AAC decoding path being used to
      // decode content decrypted by the Widevine CDM.
      if (WMFDecoderModule::HasAAC()) {
        widevine.mMP4.SetCanDecrypt(GMP_CODEC_AAC);
      }
#else
      widevine.mMP4.SetCanDecrypt(GMP_CODEC_AAC);
#endif
      widevine.mMP4.SetCanDecryptAndDecode(GMP_CODEC_H264);
      widevine.mWebM.SetCanDecrypt(GMP_CODEC_VORBIS);
      widevine.mWebM.SetCanDecrypt(GMP_CODEC_OPUS);
      widevine.mWebM.SetCanDecryptAndDecode(GMP_CODEC_VP8);
      widevine.mWebM.SetCanDecryptAndDecode(GMP_CODEC_VP9);
      sKeySystemConfigs->AppendElement(Move(widevine));
    }
    {
      KeySystemConfig primetime;
      primetime.mKeySystem = NS_ConvertUTF8toUTF16(kEMEKeySystemPrimetime);
      primetime.mInitDataTypes.AppendElement(NS_LITERAL_STRING("cenc"));
      primetime.mPersistentState = KeySystemFeatureSupport::Required;
      primetime.mDistinctiveIdentifier = KeySystemFeatureSupport::Required;
      primetime.mSessionTypes.AppendElement(MediaKeySessionType::Temporary);
      primetime.mMP4.SetCanDecryptAndDecode(GMP_CODEC_AAC);
      primetime.mMP4.SetCanDecryptAndDecode(GMP_CODEC_H264);
      sKeySystemConfigs->AppendElement(Move(primetime));
    }
  }
  return *sKeySystemConfigs;
}