void
LayerManager::StopFrameTimeRecording(nsTArray<float>& aTimes)
{
  mLastFrameTime = TimeStamp();
  aTimes.SwapElements(mFrameTimes);
  mFrameTimes.Clear();
}
/* static */ void
nsBrowserElement::GenerateAllowedAudioChannels(
                 nsPIDOMWindowInner* aWindow,
                 nsIFrameLoader* aFrameLoader,
                 nsIBrowserElementAPI* aAPI,
                 nsTArray<RefPtr<BrowserElementAudioChannel>>& aAudioChannels,
                 ErrorResult& aRv)
{
  MOZ_ASSERT(aAudioChannels.IsEmpty());

  // Normal is always allowed.
  nsTArray<RefPtr<BrowserElementAudioChannel>> channels;

  RefPtr<BrowserElementAudioChannel> ac =
    BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
                                       AudioChannel::Normal, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  channels.AppendElement(ac);

  nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
  if (NS_WARN_IF(!doc)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  // Since we don't have permissions anymore let only chrome windows pick a
  // non-default channel
  if (nsContentUtils::IsChromeDoc(doc)) {
    const nsAttrValue::EnumTable* audioChannelTable =
      AudioChannelService::GetAudioChannelTable();

    for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
      AudioChannel value = (AudioChannel)audioChannelTable[i].value;
      RefPtr<BrowserElementAudioChannel> ac =
        BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
                                           value, aRv);
      if (NS_WARN_IF(aRv.Failed())) {
        return;
      }

      channels.AppendElement(ac);
    }
  }

  aAudioChannels.SwapElements(channels);
}
nsresult
FragmentBuffer::GetFirstFragment(nsTArray<nsRefPtr<EncodedFrame>>& aFragment,
                                 bool aFlush)
{
  // It should be called only if there is a complete fragment in mFragArray.
  if (mFragArray.Length() <= 1 && !mEOS) {
    MOZ_ASSERT(false);
    return NS_ERROR_FAILURE;
  }

  if (aFlush) {
    aFragment.SwapElements(mFragArray.ElementAt(0));
    mFragArray.RemoveElementAt(0);
  } else {
    aFragment.AppendElements(mFragArray.ElementAt(0));
  }
  return NS_OK;
}
static inline nsresult WebCL_variantToInternalVector3 (JSContext* cx, nsIVariant* aVariant,
                                                       nsTArray<size_t>& aRegionOut)
{
  D_METHOD_START;
  NS_ENSURE_ARG_POINTER (cx);
  NS_ENSURE_ARG_POINTER (aVariant);
  nsresult rv;

  nsTArray<nsIVariant*> variants;
  rv = WebCL_getVariantsFromJSArray (cx, aVariant, variants);
  NS_ENSURE_SUCCESS (rv, rv);
  if (variants.Length () != 3)
  {
    D_LOG (LOG_LEVEL_ERROR, "Variant array has %d items instead of exactly 3.",
           variants.Length());
    return NS_ERROR_FAILURE;
  }

  nsTArray<size_t> result;
  result.SetCapacity (3);
  for (nsTArray<nsIVariant*>::index_type i = 0; i < variants.Length(); ++i)
  {
    PRInt32 val;
    rv = variants[i]->GetAsInt32 (&val);
    if (NS_FAILED (rv)) {
      D_LOG (LOG_LEVEL_ERROR, "Variant array index %d can not be converted to integer.",
             i);
      break;
    }
    result.AppendElement ((size_t)val);
  }
  WebCL_releaseVariantVector (variants);
  NS_ENSURE_SUCCESS (rv, rv);

  aRegionOut.SwapElements (result);
  return NS_OK;
}
void
DOMIntersectionObserver::TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal)
{
    aRetVal.SwapElements(mQueuedEntries);
    mQueuedEntries.Clear();
}
Beispiel #6
0
/* static */ void
nsBrowserElement::GenerateAllowedAudioChannels(
                 nsPIDOMWindowInner* aWindow,
                 nsIFrameLoader* aFrameLoader,
                 nsIBrowserElementAPI* aAPI,
                 const nsAString& aManifestURL,
                 mozIApplication* aParentApp,
                 nsTArray<RefPtr<BrowserElementAudioChannel>>& aAudioChannels,
                 ErrorResult& aRv)
{
  MOZ_ASSERT(aAudioChannels.IsEmpty());

  nsCOMPtr<nsIAppsService> appsService =
    do_GetService("@mozilla.org/AppsService;1");
  if (NS_WARN_IF(!appsService)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  nsCOMPtr<mozIApplication> app;
  aRv = appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  // Normal is always allowed.
  nsTArray<RefPtr<BrowserElementAudioChannel>> channels;

  RefPtr<BrowserElementAudioChannel> ac =
    BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
                                       AudioChannel::Normal,
                                       aManifestURL, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  channels.AppendElement(ac);

  if (app) {
    const nsAttrValue::EnumTable* audioChannelTable =
      AudioChannelService::GetAudioChannelTable();

    bool allowed;
    nsAutoCString permissionName;

    for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
      permissionName.AssignASCII("audio-channel-");
      permissionName.AppendASCII(audioChannelTable[i].tag);

      // In case of nested iframes we want to check if the parent has the
      // permission to use this AudioChannel.
      if (aParentApp) {
        aRv = aParentApp->HasPermission(permissionName.get(), &allowed);
        if (NS_WARN_IF(aRv.Failed())) {
          return;
        }

        if (!allowed) {
          continue;
        }
      }

      aRv = app->HasPermission(permissionName.get(), &allowed);
      if (NS_WARN_IF(aRv.Failed())) {
        return;
      }

      if (allowed) {
        RefPtr<BrowserElementAudioChannel> ac =
          BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
                                             (AudioChannel)audioChannelTable[i].value,
                                             aManifestURL, aRv);
        if (NS_WARN_IF(aRv.Failed())) {
          return;
        }

        channels.AppendElement(ac);
      }
    }
  }

  aAudioChannels.SwapElements(channels);
}
/* static */ bool
FeaturePolicyParser::ParseString(const nsAString& aPolicy,
                                 nsIDocument* aDocument,
                                 const nsAString& aSelfOrigin,
                                 const nsAString& aSrcOrigin,
                                 bool aSrcEnabled,
                                 nsTArray<Feature>& aParsedFeatures)
{
  nsTArray<nsTArray<nsString>> tokens;
  PolicyTokenizer::tokenizePolicy(aPolicy, tokens);

  nsTArray<Feature> parsedFeatures;

  for (const nsTArray<nsString>& featureTokens : tokens) {
    if (featureTokens.IsEmpty()) {
      continue;
    }

    if (!FeaturePolicyUtils::IsSupportedFeature(featureTokens[0])) {
      ReportToConsoleUnsupportedFeature(aDocument, featureTokens[0]);
      continue;
    }

    Feature feature(featureTokens[0]);

    if (featureTokens.Length() == 1) {
      if (aSrcEnabled) {
        // Note that this src origin can be empty if opaque.
        feature.AppendOriginToWhiteList(aSrcOrigin);
      } else {
        ReportToConsoleInvalidEmptyAllowValue(aDocument, featureTokens[0]);
        continue;
      }
    } else {
      // we gotta start at 1 here
      for (uint32_t i = 1; i < featureTokens.Length(); ++i) {
        const nsString& curVal = featureTokens[i];
        if (curVal.LowerCaseEqualsASCII("'none'")) {
          feature.SetAllowsNone();
          break;
        }

        if (curVal.EqualsLiteral("*")) {
          feature.SetAllowsAll();
          break;
        }

        if (curVal.LowerCaseEqualsASCII("'self'")) {
          // Opaque origins are passed as empty string.
          if (!aSelfOrigin.IsEmpty()) {
            feature.AppendOriginToWhiteList(aSelfOrigin);
          }
          continue;
        }

        if (aSrcEnabled && curVal.LowerCaseEqualsASCII("'src'")) {
          // Opaque origins are passed as empty string.
          if (!aSrcOrigin.IsEmpty()) {
            feature.AppendOriginToWhiteList(aSrcOrigin);
          }
          continue;
        }

        nsCOMPtr<nsIURI> uri;
        nsresult rv = NS_NewURI(getter_AddRefs(uri), curVal);
        if (NS_FAILED(rv)) {
          ReportToConsoleInvalidAllowValue(aDocument, curVal);
          continue;
        }

        nsAutoString origin;
        rv = nsContentUtils::GetUTFOrigin(uri, origin);
        if (NS_WARN_IF(NS_FAILED(rv))) {
          ReportToConsoleInvalidAllowValue(aDocument, curVal);
          continue;
        }

        feature.AppendOriginToWhiteList(origin);
      }
    }

    // No duplicate!
    bool found = false;
    for (const Feature& parsedFeature : parsedFeatures) {
      if (parsedFeature.Name() == feature.Name()) {
        found = true;
        break;
      }
    }

    if (!found) {
      parsedFeatures.AppendElement(feature);
    }
  }

  aParsedFeatures.SwapElements(parsedFeatures);
  return true;
}
void
PerformanceObserver::TakeRecords(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
  MOZ_ASSERT(aRetval.IsEmpty());
  aRetval.SwapElements(mQueuedEntries);
}
nsresult WebCL_getVariantsFromJSArray (JSContext *cx, nsIVariant* aVariant,
                                       nsTArray<nsIVariant*> & aResultOut)
{
  D_METHOD_START;
  nsresult rv;

  NS_ENSURE_ARG_POINTER (aVariant);
  PRUint16 variantType = 0;
  rv = aVariant->GetDataType (&variantType);
  switch (variantType)
  {
    // Accept VTYPE_ARRAY, VTYPE_EMPTY_ARRAY
    case nsIDataType::VTYPE_ARRAY:
    case nsIDataType::VTYPE_EMPTY_ARRAY:
      // Array detected
      break;
    case nsIDataType::VTYPE_INTERFACE:
    case nsIDataType::VTYPE_INTERFACE_IS:
      // Might be a proxy object holding the array
      break;

    default:
      D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not an array (type: %u).", variantType);
      return NS_ERROR_INVALID_ARG;
  }

  if (!cx)
  {
    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
    NS_ENSURE_SUCCESS (rv, rv);
    cx = stack->GetSafeJSContext ();
    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
  }
  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
  NS_ENSURE_SUCCESS (rv, rv);

  js::Value jsVal;
  rv = xpc->VariantToJS(cx, JS_GetGlobalObject(cx), aVariant, &jsVal);
  NS_ENSURE_SUCCESS (rv, rv);

  if ( !jsVal.isObject ())
  {
    D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not a JSObject.");
    return NS_ERROR_INVALID_ARG;
  }

  JSObject* jsArrObj = jsVal.toObjectOrNull ();
  if (jsArrObj && js::IsObjectProxy (jsArrObj))
  {
    jsArrObj = js::UnwrapObject (jsArrObj);
  }

  if (!jsArrObj || !JS_IsArrayObject (cx, jsArrObj))
  {
    D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not a JS Array Object.");
    return NS_ERROR_INVALID_ARG;
  }

  nsTArray <nsIVariant*> res;

  JS_BeginRequest (cx);

  JSBool ok = JS_TRUE;
  uint32_t jsArrLen = 0;
  ok = JS_GetArrayLength(cx, jsArrObj, &jsArrLen);
  if (!ok)
  {
    JS_EndRequest(cx);
    D_LOG (LOG_LEVEL_ERROR, "Failed to get array length.");
    return NS_ERROR_FAILURE;
  }

  res.SetCapacity (jsArrLen);

  for (uint32_t i = 0; i < jsArrLen; ++i)
  {
    jsval elem;
    JSBool ok = JS_GetElement (cx, jsArrObj, i, &elem);
    if (ok)
    {
      nsCOMPtr<nsIVariant> variant;
      rv = xpc->JSValToVariant (cx, &elem, getter_AddRefs(variant));
      if (NS_SUCCEEDED (rv))
      {
        res.AppendElement (variant);
        NS_ADDREF (variant);
      }
      else
      {
        D_LOG (LOG_LEVEL_WARNING,
              "Failed to convert element at position %d to nsIVariant. (rv %d)",
              i+1, rv);
      }
    }
    else
    {
        D_LOG (LOG_LEVEL_WARNING,
               "Failed to get element at position %d to nsIVariant. (rv %d)",
               i+1, rv);
    }
  }

  JS_EndRequest(cx);

  aResultOut.SwapElements (res);

  return NS_OK;
}