template <class T> void
ExtractCommonNonCDMACellInfoItems(nsCOMPtr<T>& cell, nsDataHashtable<nsCStringHashKey, int32_t>& info)
{
  int32_t mcc, mnc, cid, sig;

  cell->GetMcc(&mcc);
  cell->GetMnc(&mnc);
  cell->GetCid(&cid);
  cell->GetSignalStrength(&sig);

  info.Put(TEXT_MCC, mcc);
  info.Put(TEXT_MNC, mnc);
  info.Put(TEXT_CID, cid);
  info.Put(TEXT_STRENGTH_ASU, sig);
}
nsresult NameSpaceManagerImpl::AddNameSpace(const nsAString& aURI,
                                            const PRInt32 aNameSpaceID)
{
  if (aNameSpaceID < 0) {
    // We've wrapped...  Can't do anything else here; just bail.
    return NS_ERROR_OUT_OF_MEMORY;
  }
  
  NS_ASSERTION(aNameSpaceID - 1 == (PRInt32) mURIArray.Length(),
               "BAD! AddNameSpace not called in right order!");

  nsString* uri = new nsString(aURI);
  if (!uri || !mURIArray.AppendElement(uri)) {
    delete uri;
    return NS_ERROR_OUT_OF_MEMORY;
  }

  if (!mURIToIDTable.Put(uri, aNameSpaceID)) {
    mURIArray.RemoveElementAt(aNameSpaceID - 1);

    return NS_ERROR_OUT_OF_MEMORY;
  }

  return NS_OK;
}
void
BluetoothServiceBluedroid::SspRequestNotification(
  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod,
  BluetoothSspVariant aPairingVariant, uint32_t aPasskey)
{
  MOZ_ASSERT(NS_IsMainThread());

  InfallibleTArray<BluetoothNamedValue> propertiesArray;
  nsAutoString passkey;
  nsAutoString pairingType;

  /**
   * Assign pairing request type and passkey based on the pairing variant.
   *
   * passkey value based on pairing request type:
   * 1) aPasskey: PAIRING_REQ_TYPE_CONFIRMATION and
   *              PAIRING_REQ_TYPE_DISPLAYPASSKEY
   * 2) empty string: PAIRING_REQ_TYPE_CONSENT
   */
  switch (aPairingVariant) {
    case SSP_VARIANT_PASSKEY_CONFIRMATION:
      pairingType.AssignLiteral(PAIRING_REQ_TYPE_CONFIRMATION);
      passkey.AppendInt(aPasskey);
      break;
    case SSP_VARIANT_PASSKEY_NOTIFICATION:
      pairingType.AssignLiteral(PAIRING_REQ_TYPE_DISPLAYPASSKEY);
      passkey.AppendInt(aPasskey);
      break;
    case SSP_VARIANT_CONSENT:
      pairingType.AssignLiteral(PAIRING_REQ_TYPE_CONSENT);
      break;
    default:
      BT_WARNING("Unhandled SSP Bonding Variant: %d", aPairingVariant);
      return;
  }

  BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
  BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName));
  BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", passkey);
  BT_APPEND_NAMED_VALUE(propertiesArray, "type", pairingType);

  sPairingNameTable.Put(nsString(aRemoteBdAddr), nsString(aBdName));

  DistributeSignal(NS_LITERAL_STRING("PairingRequest"),
                   NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                   BluetoothValue(propertiesArray));
}
void
BluetoothServiceBluedroid::PinRequestNotification(const nsAString& aRemoteBdAddr,
                                                  const nsAString& aBdName,
                                                  uint32_t aCod)
{
  MOZ_ASSERT(NS_IsMainThread());

  InfallibleTArray<BluetoothNamedValue> propertiesArray;

  BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
  BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName));
  BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", EmptyString());
  BT_APPEND_NAMED_VALUE(propertiesArray, "type",
                        NS_LITERAL_STRING(PAIRING_REQ_TYPE_ENTERPINCODE));

  sPairingNameTable.Put(nsString(aRemoteBdAddr), nsString(aBdName));

  DistributeSignal(NS_LITERAL_STRING("PairingRequest"),
                   NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                   BluetoothValue(propertiesArray));
}
nsresult NameSpaceManagerImpl::AddNameSpace(const nsAString& aURI,
                                            const PRInt32 aNameSpaceID)
{
  if (aNameSpaceID < 0) {
    // We've wrapped...  Can't do anything else here; just bail.
    return NS_ERROR_OUT_OF_MEMORY;
  }
  
  NS_ASSERTION(aNameSpaceID - 1 == mURIArray.Count(),
               "BAD! AddNameSpace not called in right order!");

  if (!mURIArray.AppendString(aURI)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  const nsString* uri = mURIArray.StringAt(aNameSpaceID - 1);
  if (!mURIToIDTable.Put(uri, aNameSpaceID)) {
    mURIArray.RemoveStringAt(aNameSpaceID - 1);

    return NS_ERROR_OUT_OF_MEMORY;
  }

  return NS_OK;
}
void
DottedCornerFinder::FindBestOverlap(Float aMinR, Float aMinBorderRadius,
                                    Float aMaxBorderRadius)
{
  // If overlap is not calculateable, find it with binary search,
  // such that there exists i that C_i == C_n with the given overlap.

  FourFloats key(aMinR, mMaxR,
                 aMinBorderRadius, aMaxBorderRadius);
  BestOverlap best;
  if (DottedCornerCache.Get(key, &best)) {
    mCount = best.count;
    mBestOverlap = best.overlap;
    return;
  }

  Float lower = 0.0f;
  Float upper = 0.5f;
  // Start from lower bound to find the minimum number of circles.
  Float overlap = 0.0f;
  mBestOverlap = overlap;
  size_t targetCount = 0;

  const Float OVERLAP_MARGIN = 0.1f;
  for (size_t j = 0; j < MAX_LOOP; j++) {
    Reset();

    size_t count;
    Float actualOverlap;
    if (!GetCountAndLastOverlap(overlap, &count, &actualOverlap)) {
      if (j == 0) {
        mCount = mMaxCount;
        break;
      }
    }

    if (j == 0) {
      if (count < 3 || (count == 3 && actualOverlap > 0.5f)) {
        // |count == 3 && actualOverlap > 0.5f| means there could be
        // a circle but it is too near from both ends.
        //
        // if actualOverlap == 0.0
        //               1       2       3
        //   +-------+-------+-------+-------+
        //   | ##### | ***** | ##### | ##### |
        //   |#######|*******|#######|#######|
        //   |###+###|***+***|###+###|###+###|
        //   |# C_0 #|* C_1 *|# C_2 #|# C_n #|
        //   | ##### | ***** | ##### | ##### |
        //   +-------+-------+-------+-------+
        //                   |
        //                   V
        //   +-------+---+-------+---+-------+
        //   | ##### |   | ##### |   | ##### |
        //   |#######|   |#######|   |#######|
        //   |###+###|   |###+###|   |###+###| Find the best overlap to place
        //   |# C_0 #|   |# C_1 #|   |# C_n #| C_1 at the middle of them
        //   | ##### |   | ##### |   | ##### |
        //   +-------+---+-------+---|-------+
        //
        // if actualOverlap == 0.5
        //               1       2     3
        //   +-------+-------+-------+---+
        //   | ##### | ***** | ##### |## |
        //   |#######|*******|##### C_n #|
        //   |###+###|***+***|###+###+###|
        //   |# C_0 #|* C_1 *|# C_2 #|###|
        //   | ##### | ***** | ##### |## |
        //   +-------+-------+-------+---+
        //                 |
        //                 V
        //   +-------+-+-------+-+-------+
        //   | ##### | | ##### | | ##### |
        //   |#######| |#######| |#######|
        //   |###+###| |###+###| |###+###| Even if we place C_1 at the middle
        //   |# C_0 #| |# C_1 #| |# C_n #| of them, it's too near from them
        //   | ##### | | ##### | | ##### |
        //   +-------+-+-------+-|-------+
        //                 |
        //                 V
        //   +-------+-----------+-------+
        //   | ##### |           | ##### |
        //   |#######|           |#######|
        //   |###+###|           |###+###| Do not draw any circle
        //   |# C_0 #|           |# C_n #|
        //   | ##### |           | ##### |
        //   +-------+-----------+-------+
        mCount = 0;
        break;
      }

      // targetCount should be 2n, as we're searching C_1 to C_n.
      //
      //   targetCount = 4
      //   mCount = 1
      //               1       2       3       4
      //   +-------+-------+-------+-------+-------+
      //   | ##### | ***** | ##### | ***** | ##### |
      //   |#######|*******|#######|*******|#######|
      //   |###+###|***+***|###+###|***+***|###+###|
      //   |# C_0 #|* C_1 *|# C_2 #|* C_3 *|# C_n #|
      //   | ##### | ***** | ##### | ***** | ##### |
      //   +-------+-------+-------+-------+-------+
      //                       1
      //
      //   targetCount = 6
      //   mCount = 2
      //               1       2       3       4       5       6
      //   +-------+-------+-------+-------+-------+-------+-------+
      //   | ##### | ***** | ##### | ***** | ##### | ***** | ##### |
      //   |#######|*******|#######|*******|#######|*******|#######|
      //   |###+###|***+***|###+###|***+***|###+###|***+***|###+###|
      //   |# C_0 #|* C_1 *|# C_2 #|* C_3 *|# C_4 #|* C_5 *|# C_n #|
      //   | ##### | ***** | ##### | ***** | ##### | ***** | ##### |
      //   +-------+-------+-------+-------+-------+-------+-------+
      //                       1               2
      if (count % 2) {
        targetCount = count + 1;
      } else {
        targetCount = count;
      }

      mCount = targetCount / 2 - 1;
    }

    if (count == targetCount) {
      mBestOverlap = overlap;

      if (fabs(actualOverlap - overlap) < OVERLAP_MARGIN) {
        break;
      }

      // We started from upper bound, no need to update range when j == 0.
      if (j > 0) {
        if (actualOverlap > overlap) {
          lower = overlap;
        } else {
          upper = overlap;
        }
      }
    } else {
      // |j == 0 && count != targetCount| means that |targetCount = count + 1|,
      // and we started from upper bound, no need to update range when j == 0.
      if (j > 0) {
        if (count > targetCount) {
          upper = overlap;
        } else {
          lower = overlap;
        }
      }
    }

    overlap = (upper + lower) / 2.0f;
  }

  if (DottedCornerCache.Count() > DottedCornerCacheSize) {
    DottedCornerCache.Clear();
  }
  DottedCornerCache.Put(key, BestOverlap(mBestOverlap, mCount));
}