static void
BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
                         bt_bond_state_t aState)
{
  MOZ_ASSERT(!NS_IsMainThread());

  nsAutoString remoteAddress;
  BdAddressTypeToString(aRemoteBdAddress, remoteAddress);

  // We don't need to handle bonding state
  NS_ENSURE_TRUE_VOID(aState != BT_BOND_STATE_BONDING);
  NS_ENSURE_FALSE_VOID(aState == BT_BOND_STATE_BONDED &&
                       sAdapterBondedAddressArray.Contains(remoteAddress));
  bool bonded;
  if (aState == BT_BOND_STATE_NONE) {
    bonded = false;
    sAdapterBondedAddressArray.RemoveElement(remoteAddress);
  } else if (aState == BT_BOND_STATE_BONDED) {
    bonded = true;
    sAdapterBondedAddressArray.AppendElement(remoteAddress);
  }

  // Update bonded address list to BluetoothAdapter
  InfallibleTArray<BluetoothNamedValue> propertiesChangeArray;
  propertiesChangeArray.AppendElement(
    BluetoothNamedValue(NS_LITERAL_STRING("Devices"),
                        sAdapterBondedAddressArray));
  BluetoothValue value(propertiesChangeArray);
  BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
                         NS_LITERAL_STRING(KEY_ADAPTER),
                         BluetoothValue(propertiesChangeArray));
  NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal));

  // Update bonding status to gaia
  InfallibleTArray<BluetoothNamedValue> propertiesArray;
  propertiesArray.AppendElement(
    BluetoothNamedValue(NS_LITERAL_STRING("address"), remoteAddress));
  propertiesArray.AppendElement(
    BluetoothNamedValue(NS_LITERAL_STRING("status"), bonded));
  BluetoothSignal newSignal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID),
                            NS_LITERAL_STRING(KEY_ADAPTER),
                            BluetoothValue(propertiesArray));
  NS_DispatchToMainThread(new DistributeBluetoothSignalTask(newSignal));

  if (bonded && !sBondingRunnableArray.IsEmpty()) {
    DispatchBluetoothReply(sBondingRunnableArray[0],
                           BluetoothValue(true), EmptyString());

    sBondingRunnableArray.RemoveElementAt(0);
  } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
    DispatchBluetoothReply(sUnbondingRunnableArray[0],
                           BluetoothValue(true), EmptyString());

    sUnbondingRunnableArray.RemoveElementAt(0);
  }
}
nsresult
PendingLookup::LookupNext()
{
  // We must call LookupNext or SendRemoteQuery upon return.
  // Look up all of the URLs that could allow or block this download.
  // Blocklist first.
  if (mBlocklistCount > 0) {
    return OnComplete(true, NS_OK);
  }
  int index = mAnylistSpecs.Length() - 1;
  nsCString spec;
  if (index >= 0) {
    // Check the source URI, referrer and redirect chain.
    spec = mAnylistSpecs[index];
    mAnylistSpecs.RemoveElementAt(index);
    nsRefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
    return lookup->LookupSpec(spec, false);
  }
  // If any of mAnylistSpecs matched the blocklist, go ahead and block.
  if (mBlocklistCount > 0) {
    return OnComplete(true, NS_OK);
  }
  // If any of mAnylistSpecs matched the allowlist, go ahead and pass.
  if (mAllowlistCount > 0) {
    return OnComplete(false, NS_OK);
  }
  // Only binary signatures remain.
  index = mAllowlistSpecs.Length() - 1;
  if (index >= 0) {
    spec = mAllowlistSpecs[index];
    LOG(("PendingLookup::LookupNext: checking %s on allowlist", spec.get()));
    mAllowlistSpecs.RemoveElementAt(index);
    nsRefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
    return lookup->LookupSpec(spec, true);
  }
#ifdef XP_WIN
  // There are no more URIs to check against local list. If the file is
  // not eligible for remote lookup, bail.
  if (!IsBinaryFile()) {
    LOG(("Not eligible for remote lookups [this=%x]", this));
    return OnComplete(false, NS_OK);
  }
  // Send the remote query if we are on Windows.
  nsresult rv = SendRemoteQuery();
  if (NS_FAILED(rv)) {
    return OnComplete(false, rv);
  }
  return NS_OK;
#else
  LOG(("PendingLookup: Nothing left to check [this=%p]", this));
  return OnComplete(false, NS_OK);
#endif
}
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;
}
Example #4
0
void
WindowsGamepadService::ScanForDevices()
{
  for (int i = mGamepads.Length() - 1; i >= 0; i--) {
    mGamepads[i].present = false;
  }

  if (mHID) {
    ScanForRawInputDevices();
  }
  if (mXInput) {
    mXInputPollTimer->Cancel();
    if (ScanForXInputDevices()) {
      mXInputPollTimer->InitWithFuncCallback(XInputPollTimerCallback,
                                             this,
                                             kXInputPollInterval,
                                             nsITimer::TYPE_REPEATING_SLACK);
    }
  }

  // Look for devices that are no longer present and remove them.
  for (int i = mGamepads.Length() - 1; i >= 0; i--) {
    if (!mGamepads[i].present) {
      RemoveGamepad(mGamepads[i].id);
      mGamepads.RemoveElementAt(i);
    }
  }
}
/**
 * AdapterPropertiesNotification will be called after enable() but
 * before AdapterStateChangeNotification is called. At that moment,
 * BluetoothManager and BluetoothAdapter, do not register observer
 * yet.
 */
void
BluetoothServiceBluedroid::AdapterPropertiesNotification(
  BluetoothStatus aStatus, int aNumProperties,
  const BluetoothProperty* aProperties)
{
  MOZ_ASSERT(NS_IsMainThread());

  InfallibleTArray<BluetoothNamedValue> propertiesArray;

  for (int i = 0; i < aNumProperties; i++) {

    const BluetoothProperty& p = aProperties[i];

    if (p.mType == PROPERTY_BDADDR) {
      sAdapterBdAddress = p.mString;
      BT_APPEND_NAMED_VALUE(propertiesArray, "Address", sAdapterBdAddress);

    } else if (p.mType == PROPERTY_BDNAME) {
      sAdapterBdName = p.mString;
      BT_APPEND_NAMED_VALUE(propertiesArray, "Name", sAdapterBdName);

    } else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) {
      sAdapterDiscoverable =
        (p.mScanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE);
      BT_APPEND_NAMED_VALUE(propertiesArray, "Discoverable",
                            sAdapterDiscoverable);

    } else if (p.mType == PROPERTY_ADAPTER_BONDED_DEVICES) {
      // We have to cache addresses of bonded devices. Unlike BlueZ,
      // Bluedroid would not send another PROPERTY_ADAPTER_BONDED_DEVICES
      // event after bond completed.
      BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d",
              p.mStringArray.Length());

      // Whenever reloading paired devices, force refresh
      sAdapterBondedAddressArray.Clear();
      sAdapterBondedAddressArray.AppendElements(p.mStringArray);

      BT_APPEND_NAMED_VALUE(propertiesArray, "PairedDevices",
                            sAdapterBondedAddressArray);
    } else if (p.mType == PROPERTY_UNKNOWN) {
      /* Bug 1065999: working around unknown properties */
    } else {
      BT_LOGD("Unhandled adapter property type: %d", p.mType);
      continue;
    }
  }

  NS_ENSURE_TRUE_VOID(propertiesArray.Length() > 0);

  DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                   NS_LITERAL_STRING(KEY_ADAPTER),
                   BluetoothValue(propertiesArray));

  // Send reply for SetProperty
  if (!sSetPropertyRunnableArray.IsEmpty()) {
    DispatchReplySuccess(sSetPropertyRunnableArray[0]);
    sSetPropertyRunnableArray.RemoveElementAt(0);
  }
}
Example #6
0
 static void DestroyLast(nsTArray<nsEventTargetChainItem>& aChain,
                         nsEventTargetChainItem* aItem)
 {
   uint32_t lastIndex = aChain.Length() - 1;
   MOZ_ASSERT(&aChain[lastIndex] == aItem);
   aChain.RemoveElementAt(lastIndex);
 }
nsresult
ICameraControl::GetListOfCameras(nsTArray<nsString>& aList)
{
  int32_t count = android::Camera::getNumberOfCameras();
  DOM_CAMERA_LOGI("getListOfCameras : getNumberOfCameras() returned %d\n", count);
  if (count <= 0) {
    aList.Clear();
    return NS_OK;
  }

  // Allocate 2 extra slots to reserve space for 'front' and 'back' cameras
  // at the front of the array--we will collapse any empty slots below.
  aList.SetLength(2);
  uint32_t extraIdx = 2;
  bool gotFront = false;
  bool gotBack = false;
  while (count--) {
    nsCString cameraName;
    nsresult result = GetCameraName(count, cameraName);
    if (result != NS_OK) {
      continue;
    }

    // The first camera we find named 'back' gets slot 0; and the first
    // we find named 'front' gets slot 1.  All others appear after these.
    if (cameraName.EqualsLiteral("back")) {
      CopyUTF8toUTF16(cameraName, aList[0]);
      gotBack = true;
    } else if (cameraName.EqualsLiteral("front")) {
      CopyUTF8toUTF16(cameraName, aList[1]);
      gotFront = true;
    } else {
      CopyUTF8toUTF16(cameraName, *aList.InsertElementAt(extraIdx));
      extraIdx++;
    }
  }

  if (!gotFront) {
    aList.RemoveElementAt(1);
  }

  if (!gotBack) {
    aList.RemoveElementAt(0);
  }

  return NS_OK;
}
  void OnError(BluetoothStatus aStatus) override
  {
    MOZ_ASSERT(NS_IsMainThread());

    BT_WARNING("GetRemoteDeviceProperties(%s) failed: %d",
               NS_ConvertUTF16toUTF8(mDeviceAddress).get(), aStatus);

    /* dispatch result after final pending operation */
    if (--sRequestedDeviceCountArray[0] == 0) {
      if (!sGetDeviceRunnableArray.IsEmpty()) {
        DispatchReplyError(sGetDeviceRunnableArray[0],
          NS_LITERAL_STRING("GetRemoteDeviceProperties failed"));
        sGetDeviceRunnableArray.RemoveElementAt(0);
      }

      sRequestedDeviceCountArray.RemoveElementAt(0);
      sRemoteDevicesPack.Clear();
    }
  }
static void
NextBluetoothProfileController()
{
  sControllerArray[0] = nullptr;
  sControllerArray.RemoveElementAt(0);

  if (!sControllerArray.IsEmpty()) {
    sControllerArray[0]->Start();
  }
}
static void
NextBluetoothProfileController()
{
  MOZ_ASSERT(NS_IsMainThread());

  // First, remove the task at the front which has been already done.
  NS_ENSURE_FALSE_VOID(sControllerArray.IsEmpty());
  sControllerArray.RemoveElementAt(0);
  // Re-check if the task array is empty, if it's not, the next task will begin.
  NS_ENSURE_FALSE_VOID(sControllerArray.IsEmpty());
  sControllerArray[0]->StartSession();
}
Example #11
0
NS_IMETHODIMP
nsCommandLine::RemoveArguments(int32_t aStart, int32_t aEnd)
{
  NS_ENSURE_ARG_MIN(aStart, 0);
  NS_ENSURE_ARG_MAX(uint32_t(aEnd) + 1, mArgs.Length());

  for (int32_t i = aEnd; i >= aStart; --i) {
    mArgs.RemoveElementAt(i);
  }

  return NS_OK;
}
static void
DiscoveryStateChangedCallback(bt_discovery_state_t aState)
{
  MOZ_ASSERT(!NS_IsMainThread());

  if (!sChangeDiscoveryRunnableArray.IsEmpty()) {
    BluetoothValue values(true);
    DispatchBluetoothReply(sChangeDiscoveryRunnableArray[0],
                           values, EmptyString());

    sChangeDiscoveryRunnableArray.RemoveElementAt(0);
  }
}
void
BluetoothServiceBluedroid::NextBluetoothProfileController()
{
  MOZ_ASSERT(NS_IsMainThread());

  // Remove the completed task at the head
  NS_ENSURE_FALSE_VOID(sControllerArray.IsEmpty());
  sControllerArray.RemoveElementAt(0);

  // Start the next task if task array is not empty
  if (!sControllerArray.IsEmpty()) {
    sControllerArray[0]->StartSession();
  }
}
Example #14
0
void
DBusWatcher::HandleWatchRemove()
{
  int fd;
  ssize_t res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &fd, sizeof(fd)));
  if (res < 0) {
    LOG("Cannot read DBus watch remove descriptor data from socket!\n");
    return;
  }

  unsigned int flags;
  res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &flags, sizeof(flags)));
  if (res < 0) {
    LOG("Cannot read DBus watch remove flag data from socket!\n");
    return;
  }

  struct pollfd p = {
    fd, // .fd
    DBusFlagsToUnixEvents(flags), // .events
    0 // .revents
  };
  int index = mPollData.IndexOf(p, 0, PollFdComparator());
  // There are times where removes can be requested for watches that
  // haven't been added (for example, whenever gecko comes up after
  // adapters have already been enabled), so check to make sure we're
  // using the watch in the first place
  if (index < 0) {
    LOG("DBus requested watch removal of non-existant socket, ignoring...");
    return;
  }
  mPollData.RemoveElementAt(index);

  // DBusWatch pointers are maintained by DBus, so we won't leak by
  // removing.
  mWatchData.RemoveElementAt(index);
}
Example #15
0
template<class T> static void
DoDeferredRelease(nsTArray<T> &array)
{
    while(1)
    {
        PRUint32 count = array.Length();
        if(!count)
        {
            array.Compact();
            break;
        }
        T wrapper = array[count-1];
        array.RemoveElementAt(count-1);
        NS_RELEASE(wrapper);
    }
}
nsresult
nsUrlClassifierDBServiceWorker::HandlePendingLookups()
{
  MutexAutoLock lock(mPendingLookupLock);
  while (mPendingLookups.Length() > 0) {
    PendingLookup lookup = mPendingLookups[0];
    mPendingLookups.RemoveElementAt(0);
    {
      MutexAutoUnlock unlock(mPendingLookupLock);
      DoLookup(lookup.mKey, lookup.mCallback);
    }
    double lookupTime = (TimeStamp::Now() - lookup.mStartTime).ToMilliseconds();
    Telemetry::Accumulate(Telemetry::URLCLASSIFIER_LOOKUP_TIME,
                          static_cast<PRUint32>(lookupTime));
  }

  return NS_OK;
}
void
BluetoothServiceBluedroid::DiscoveryStateChangedNotification(bool aState)
{
  MOZ_ASSERT(NS_IsMainThread());

  sAdapterDiscovering = aState;

  // Fire PropertyChanged of Discovering
  InfallibleTArray<BluetoothNamedValue> propertiesArray;
  BT_APPEND_NAMED_VALUE(propertiesArray, "Discovering", sAdapterDiscovering);

  DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                   NS_LITERAL_STRING(KEY_ADAPTER),
                   BluetoothValue(propertiesArray));

  // Reply that Promise is resolved
  if (!sChangeDiscoveryRunnableArray.IsEmpty()) {
    DispatchReplySuccess(sChangeDiscoveryRunnableArray[0]);
    sChangeDiscoveryRunnableArray.RemoveElementAt(0);
  }
}
nsresult
BluetoothDaemonConnectionIO::SendPendingData(int aFd)
{
  while (HasPendingData()) {
    BluetoothDaemonPDU* outgoing = mOutgoingQ.ElementAt(0);
    MOZ_ASSERT(outgoing);

    ssize_t res = outgoing->Send(aFd);
    if (res < 0) {
      /* an I/O error occured */
      return NS_ERROR_FAILURE;
    } else if (!res) {
      /* I/O is currently blocked; try again later */
      return NS_OK;
    }

    MOZ_ASSERT(!outgoing->GetSize());
    mOutgoingQ.RemoveElementAt(0);
    delete outgoing;
  }

  return NS_OK;
}
Example #19
0
already_AddRefed<nsFontMetrics>
nsFontCache::GetMetricsFor(const nsFont& aFont,
                           const nsFontMetrics::Params& aParams)
{
    nsIAtom* language = aParams.language ? aParams.language
                                         : mLocaleLanguage.get();

    // First check our cache
    // start from the end, which is where we put the most-recent-used element

    int32_t n = mFontMetrics.Length() - 1;
    for (int32_t i = n; i >= 0; --i) {
        nsFontMetrics* fm = mFontMetrics[i];
        if (fm->Font().Equals(aFont) &&
            fm->GetUserFontSet() == aParams.userFontSet &&
            fm->Language() == language &&
            fm->Orientation() == aParams.orientation) {
            if (i != n) {
                // promote it to the end of the cache
                mFontMetrics.RemoveElementAt(i);
                mFontMetrics.AppendElement(fm);
            }
            fm->GetThebesFontGroup()->UpdateUserFonts();
            return do_AddRef(Move(fm));
        }
    }

    // It's not in the cache. Get font metrics and then cache them.

    nsFontMetrics::Params params = aParams;
    params.language = language;
    RefPtr<nsFontMetrics> fm = new nsFontMetrics(aFont, params, mContext);
    // the mFontMetrics list has the "head" at the end, because append
    // is cheaper than insert
    mFontMetrics.AppendElement(do_AddRef(fm.get()).take());
    return fm.forget();
}
/**
 * RemoteDevicePropertiesCallback will be called, as the following conditions:
 * 1. When BT is turning on, bluedroid automatically execute this callback
 * 2. When get_remote_device_properties()
 */
static void
RemoteDevicePropertiesCallback(bt_status_t aStatus, bt_bdaddr_t *aBdAddress,
                               int aNumProperties, bt_property_t *aProperties)
{
  MOZ_ASSERT(!NS_IsMainThread());

  if (sRequestedDeviceCountArray.IsEmpty()) {
    MOZ_ASSERT(sGetDeviceRunnableArray.IsEmpty());
    return;
  }

  sRequestedDeviceCountArray[0]--;

  InfallibleTArray<BluetoothNamedValue> props;

  nsString remoteDeviceBdAddress;
  BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
  props.AppendElement(
    BluetoothNamedValue(NS_LITERAL_STRING("Address"), remoteDeviceBdAddress));

  for (int i = 0; i < aNumProperties; ++i) {
    bt_property_t p = aProperties[i];

    if (p.type == BT_PROPERTY_BDNAME) {
      BluetoothValue propertyValue = NS_ConvertUTF8toUTF16((char*)p.val);
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
    } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) {
      uint32_t cod = *(uint32_t*)p.val;
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Class"), BluetoothValue(cod)));

      nsString icon;
      ClassToIcon(cod, icon);
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Icon"), BluetoothValue(icon)));
    } else {
      BT_LOGD("Other non-handled device properties. Type: %d", p.type);
    }
  }

  // Update to registered BluetoothDevice objects
  BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
                         remoteDeviceBdAddress, props);
  nsRefPtr<DistributeBluetoothSignalTask>
    t = new DistributeBluetoothSignalTask(signal);
  if (NS_FAILED(NS_DispatchToMainThread(t))) {
    BT_WARNING("Failed to dispatch to main thread!");
  }

  // Use address as the index
  sRemoteDevicesPack.AppendElement(
    BluetoothNamedValue(remoteDeviceBdAddress, props));

  if (sRequestedDeviceCountArray[0] == 0) {
    MOZ_ASSERT(!sGetDeviceRunnableArray.IsEmpty());

    if (sGetDeviceRunnableArray.IsEmpty()) {
      BT_LOGR("No runnable to return");
      return;
    }

    DispatchBluetoothReply(sGetDeviceRunnableArray[0],
                           sRemoteDevicesPack, EmptyString());

    // After firing it, clean up cache
    sRemoteDevicesPack.Clear();

    sRequestedDeviceCountArray.RemoveElementAt(0);
    sGetDeviceRunnableArray.RemoveElementAt(0);
  }
}
/**
 * AdapterPropertiesCallback will be called after enable() but before
 * AdapterStateChangeCallback sIsBtEnabled get updated. At that moment, both
 * BluetoothManager/BluetoothAdapter does not register observer yet.
 */
static void
AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties,
                          bt_property_t *aProperties)
{
  MOZ_ASSERT(!NS_IsMainThread());

  BluetoothValue propertyValue;
  InfallibleTArray<BluetoothNamedValue> props;

  for (int i = 0; i < aNumProperties; i++) {
    bt_property_t p = aProperties[i];

    if (p.type == BT_PROPERTY_BDADDR) {
      BdAddressTypeToString((bt_bdaddr_t*)p.val, sAdapterBdAddress);
      propertyValue = sAdapterBdAddress;
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Address"), propertyValue));
    } else if (p.type == BT_PROPERTY_BDNAME) {
      // Construct nsCString here because Bd name returned from bluedroid
      // is missing a null terminated character after SetProperty.
      propertyValue = sAdapterBdName = NS_ConvertUTF8toUTF16(
        nsCString((char*)p.val, p.len));
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
    } else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) {
      bt_scan_mode_t newMode = *(bt_scan_mode_t*)p.val;

      if (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
        propertyValue = sAdapterDiscoverable = true;
      } else {
        propertyValue = sAdapterDiscoverable = false;
      }

      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Discoverable"), propertyValue));
    } else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
      propertyValue = sAdapterDiscoverableTimeout = *(uint32_t*)p.val;
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("DiscoverableTimeout"),
                            propertyValue));
    } else if (p.type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
      // We have to cache addresses of bonded devices. Unlike BlueZ,
      // bluedroid would not send an another BT_PROPERTY_ADAPTER_BONDED_DEVICES
      // event after bond completed
      bt_bdaddr_t* deviceBdAddressTypes = (bt_bdaddr_t*)p.val;
      int numOfAddresses = p.len / BLUETOOTH_ADDRESS_BYTES;
      BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d", numOfAddresses);

      // Whenever reloading paired devices, force refresh
      sAdapterBondedAddressArray.Clear();

      for (int index = 0; index < numOfAddresses; index++) {
        nsAutoString deviceBdAddress;
        BdAddressTypeToString(deviceBdAddressTypes + index, deviceBdAddress);
        sAdapterBondedAddressArray.AppendElement(deviceBdAddress);
      }

      propertyValue = sAdapterBondedAddressArray;
      props.AppendElement(
        BluetoothNamedValue(NS_LITERAL_STRING("Devices"), propertyValue));
    } else if (p.type == BT_PROPERTY_UUIDS) {
      //FIXME: This will be implemented in the later patchset
      continue;
    } else {
      BT_LOGD("Unhandled adapter property type: %d", p.type);
      continue;
    }
  }

  NS_ENSURE_TRUE_VOID(props.Length() > 0);

  BluetoothValue value(props);
  BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
                         NS_LITERAL_STRING(KEY_ADAPTER), value);
  nsRefPtr<DistributeBluetoothSignalTask>
    t = new DistributeBluetoothSignalTask(signal);
  if (NS_FAILED(NS_DispatchToMainThread(t))) {
    BT_WARNING("Failed to dispatch to main thread!");
  }

  // bluedroid BTU task was stored in the task queue, see GKI_send_msg
  if (!sSetPropertyRunnableArray.IsEmpty()) {
    DispatchBluetoothReply(sSetPropertyRunnableArray[0], BluetoothValue(true),
                           EmptyString());
    sSetPropertyRunnableArray.RemoveElementAt(0);
  }
}
nsresult
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
  gfxUserFontSet* aUserFontSet, nsIFontMetrics*& aMetrics)
{
    // First check our cache
    // start from the end, which is where we put the most-recent-used element

    nsIFontMetrics* fm;
    PRInt32 n = mFontMetrics.Length() - 1;
    for (PRInt32 i = n; i >= 0; --i) {
        fm = mFontMetrics[i];
        nsIThebesFontMetrics* tfm = static_cast<nsIThebesFontMetrics*>(fm);
        if (fm->Font().Equals(aFont) && tfm->GetUserFontSet() == aUserFontSet) {
            nsCOMPtr<nsIAtom> language;
            fm->GetLanguage(getter_AddRefs(language));
            if (aLanguage == language.get()) {
                if (i != n) {
                    // promote it to the end of the cache
                    mFontMetrics.RemoveElementAt(i);
                    mFontMetrics.AppendElement(fm);
                }
                tfm->GetThebesFontGroup()->UpdateFontList();
                NS_ADDREF(aMetrics = fm);
                return NS_OK;
            }
        }
    }

    // It's not in the cache. Get font metrics and then cache them.

    aMetrics = nsnull;
    nsresult rv = CreateFontMetricsInstance(&fm);
    if (NS_FAILED(rv)) return rv;
    rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
    if (NS_SUCCEEDED(rv)) {
        // the mFontMetrics list has the "head" at the end, because append
        // is cheaper than insert
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        NS_ADDREF(aMetrics);
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // One reason why Init() fails is because the system is running out of
    // resources. e.g., on Win95/98 only a very limited number of GDI
    // objects are available. Compact the cache and try again.

    Compact();
    rv = CreateFontMetricsInstance(&fm);
    if (NS_FAILED(rv)) return rv;
    rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
    if (NS_SUCCEEDED(rv)) {
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        NS_ADDREF(aMetrics);
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // could not setup a new one, send an old one (XXX search a "best
    // match"?)

    n = mFontMetrics.Length() - 1; // could have changed in Compact()
    if (n >= 0) {
        aMetrics = mFontMetrics[n];
        NS_ADDREF(aMetrics);
        return NS_OK;
    }

    NS_POSTCONDITION(NS_SUCCEEDED(rv), "font metrics should not be null - bug 136248");
    return rv;
}
void
BluetoothServiceBluedroid::BondStateChangedNotification(
  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
  BluetoothBondState aState)
{
  MOZ_ASSERT(NS_IsMainThread());

  if (aState == BOND_STATE_BONDING) {
    // No need to handle bonding state
    return;
  }

  BT_LOGR("Bond state: %d status: %d", aState, aStatus);

  bool bonded = (aState == BOND_STATE_BONDED);
  if (aStatus != STATUS_SUCCESS) {
    if (!bonded) { // Active/passive pair failed
      BT_LOGR("Pair failed! Abort pairing.");

      // Notify adapter of pairing aborted
      DistributeSignal(NS_LITERAL_STRING(PAIRING_ABORTED_ID),
                       NS_LITERAL_STRING(KEY_ADAPTER));

      // Reject pair promise
      if (!sBondingRunnableArray.IsEmpty()) {
        DispatchReplyError(sBondingRunnableArray[0], aStatus);
        sBondingRunnableArray.RemoveElementAt(0);
      }
    } else if (!sUnbondingRunnableArray.IsEmpty()) { // Active unpair failed
      // Reject unpair promise
      DispatchReplyError(sUnbondingRunnableArray[0], aStatus);
      sUnbondingRunnableArray.RemoveElementAt(0);
    }

    return;
  }

  // Retrieve and remove pairing device name from hash table
  nsString deviceName;
  bool nameExists = sPairingNameTable.Get(aRemoteBdAddr, &deviceName);
  if (nameExists) {
    sPairingNameTable.Remove(aRemoteBdAddr);
  }

  // Update bonded address array and append pairing device name
  InfallibleTArray<BluetoothNamedValue> propertiesArray;
  nsString remoteBdAddr = nsString(aRemoteBdAddr);
  if (!bonded) {
    sAdapterBondedAddressArray.RemoveElement(remoteBdAddr);
  } else {
    if (!sAdapterBondedAddressArray.Contains(remoteBdAddr)) {
      sAdapterBondedAddressArray.AppendElement(remoteBdAddr);
    }

    // We don't assert |!deviceName.IsEmpty()| here since empty string is
    // also a valid name. According to Bluetooth Core Spec. v3.0 - Sec. 6.22,
    // "a valid Bluetooth name is a UTF-8 encoding string which is up to 248
    // bytes in length."
    MOZ_ASSERT(nameExists);
    BT_APPEND_NAMED_VALUE(propertiesArray, "Name", deviceName);
  }

  // Notify device of attribute changed
  BT_APPEND_NAMED_VALUE(propertiesArray, "Paired", bonded);
  DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                   aRemoteBdAddr,
                   BluetoothValue(propertiesArray));

  // Notify adapter of device paired/unpaired
  BT_INSERT_NAMED_VALUE(propertiesArray, 0, "Address", remoteBdAddr);
  DistributeSignal(bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID)
                          : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID),
                   NS_LITERAL_STRING(KEY_ADAPTER),
                   BluetoothValue(propertiesArray));

  // Resolve existing pair/unpair promise
  if (bonded && !sBondingRunnableArray.IsEmpty()) {
    DispatchReplySuccess(sBondingRunnableArray[0]);
    sBondingRunnableArray.RemoveElementAt(0);
  } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
    DispatchReplySuccess(sUnbondingRunnableArray[0]);
    sUnbondingRunnableArray.RemoveElementAt(0);
  }
}
/**
 * RemoteDevicePropertiesNotification will be called
 *
 *   (1) automatically by Bluedroid when BT is turning on,
 *   (2) as result of GetRemoteDeviceProperties, or
 *   (3) as result of GetRemoteServices.
 */
void
BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
  BluetoothStatus aStatus, const nsAString& aBdAddr,
  int aNumProperties, const BluetoothProperty* aProperties)
{
  MOZ_ASSERT(NS_IsMainThread());

  InfallibleTArray<BluetoothNamedValue> propertiesArray;

  BT_APPEND_NAMED_VALUE(propertiesArray, "Address", nsString(aBdAddr));

  for (int i = 0; i < aNumProperties; ++i) {

    const BluetoothProperty& p = aProperties[i];

    if (p.mType == PROPERTY_BDNAME) {
      BT_APPEND_NAMED_VALUE(propertiesArray, "Name", p.mString);

    } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
      uint32_t cod = p.mUint32;
      BT_APPEND_NAMED_VALUE(propertiesArray, "Cod", cod);

    } else if (p.mType == PROPERTY_UUIDS) {
      nsTArray<nsString> uuids;

      // Construct a sorted uuid set
      for (uint32_t index = 0; index < p.mUuidArray.Length(); ++index) {
        nsAutoString uuid;
        UuidToString(p.mUuidArray[index], uuid);

        if (!uuids.Contains(uuid)) { // filter out duplicate uuids
          uuids.InsertElementSorted(uuid);
        }
      }
      BT_APPEND_NAMED_VALUE(propertiesArray, "UUIDs", uuids);

    } else if (p.mType == PROPERTY_TYPE_OF_DEVICE) {
      BT_APPEND_NAMED_VALUE(propertiesArray, "Type",
                            static_cast<uint32_t>(p.mTypeOfDevice));

    } else if (p.mType == PROPERTY_UNKNOWN) {
      /* Bug 1065999: working around unknown properties */
    } else {
      BT_LOGD("Other non-handled device properties. Type: %d", p.mType);
    }
  }

  // The order of operations below is
  //
  //  (1) modify global state (i.e., the variables starting with 's'),
  //  (2) distribute the signal, and finally
  //  (3) send any pending Bluetooth replies.
  //
  // |DispatchReplySuccess| creates its own internal runnable, which is
  // always run after we completed the current method. This means that we
  // can exchange |DispatchReplySuccess| with other operations without
  // changing the order of (1,2) and (3).

  // Update to registered BluetoothDevice objects
  BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
                         nsString(aBdAddr), propertiesArray);

  // FetchUuids task
  if (!sFetchUuidsRunnableArray.IsEmpty()) {
    // propertiesArray contains Address and Uuids only
    DispatchReplySuccess(sFetchUuidsRunnableArray[0],
                         propertiesArray[1].value()); /* Uuids */
    sFetchUuidsRunnableArray.RemoveElementAt(0);
    DistributeSignal(signal);
    return;
  }

  // GetDevices task
  if (sRequestedDeviceCountArray.IsEmpty()) {
    // This is possible because the callback would be called after turning
    // Bluetooth on.
    DistributeSignal(signal);
    return;
  }

  // Use address as the index
  sRemoteDevicesPack.AppendElement(
    BluetoothNamedValue(nsString(aBdAddr), propertiesArray));

  if (--sRequestedDeviceCountArray[0] == 0) {
    if (!sGetDeviceRunnableArray.IsEmpty()) {
      DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
      sGetDeviceRunnableArray.RemoveElementAt(0);
    }

    sRequestedDeviceCountArray.RemoveElementAt(0);
    sRemoteDevicesPack.Clear();
  }

  DistributeSignal(signal);
}
Example #25
0
nsresult
nsFontCache::GetMetricsFor(const nsFont& aFont,
                           nsIAtom* aLanguage, bool aExplicitLanguage,
                           gfxFont::Orientation aOrientation,
                           gfxUserFontSet* aUserFontSet,
                           gfxTextPerfMetrics* aTextPerf,
                           nsFontMetrics*& aMetrics)
{
    if (!aLanguage)
        aLanguage = mLocaleLanguage;

    // First check our cache
    // start from the end, which is where we put the most-recent-used element

    nsFontMetrics* fm;
    int32_t n = mFontMetrics.Length() - 1;
    for (int32_t i = n; i >= 0; --i) {
        fm = mFontMetrics[i];
        if (fm->Font().Equals(aFont) && fm->GetUserFontSet() == aUserFontSet &&
            fm->Language() == aLanguage && fm->Orientation() == aOrientation) {
            if (i != n) {
                // promote it to the end of the cache
                mFontMetrics.RemoveElementAt(i);
                mFontMetrics.AppendElement(fm);
            }
            fm->GetThebesFontGroup()->UpdateUserFonts();
            NS_ADDREF(aMetrics = fm);
            return NS_OK;
        }
    }

    // It's not in the cache. Get font metrics and then cache them.

    fm = new nsFontMetrics();
    NS_ADDREF(fm);
    nsresult rv = fm->Init(aFont, aLanguage, aExplicitLanguage, aOrientation,
                           mContext, aUserFontSet, aTextPerf);
    if (NS_SUCCEEDED(rv)) {
        // the mFontMetrics list has the "head" at the end, because append
        // is cheaper than insert
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        NS_ADDREF(aMetrics);
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // One reason why Init() fails is because the system is running out of
    // resources. e.g., on Win95/98 only a very limited number of GDI
    // objects are available. Compact the cache and try again.

    Compact();
    fm = new nsFontMetrics();
    NS_ADDREF(fm);
    rv = fm->Init(aFont, aLanguage, aExplicitLanguage, aOrientation, mContext,
                  aUserFontSet, aTextPerf);
    if (NS_SUCCEEDED(rv)) {
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // could not setup a new one, send an old one (XXX search a "best
    // match"?)

    n = mFontMetrics.Length() - 1; // could have changed in Compact()
    if (n >= 0) {
        aMetrics = mFontMetrics[n];
        NS_ADDREF(aMetrics);
        return NS_OK;
    }

    NS_POSTCONDITION(NS_SUCCEEDED(rv),
                     "font metrics should not be null - bug 136248");
    return rv;
}
void
BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
{
  MOZ_ASSERT(NS_IsMainThread());

  BT_LOGR("BT_STATE: %d", aState);

  sAdapterEnabled = aState;

  if (!sAdapterEnabled) {
    static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
      BluetoothHfpManager::DeinitHfpInterface,
      BluetoothA2dpManager::DeinitA2dpInterface,
      BluetoothGattManager::DeinitGattInterface
    };

    // Return error if BluetoothService is unavailable
    BluetoothService* bs = BluetoothService::Get();
    NS_ENSURE_TRUE_VOID(bs);

    // Cleanup static adapter properties and notify adapter.
    sAdapterBdAddress.Truncate();
    sAdapterBdName.Truncate();

    InfallibleTArray<BluetoothNamedValue> props;
    BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName);
    BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress);
    if (sAdapterDiscoverable) {
      sAdapterDiscoverable = false;
      BT_APPEND_NAMED_VALUE(props, "Discoverable", false);
    }
    if (sAdapterDiscovering) {
      sAdapterDiscovering = false;
      BT_APPEND_NAMED_VALUE(props, "Discovering", false);
    }

    bs->DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                         NS_LITERAL_STRING(KEY_ADAPTER),
                         BluetoothValue(props));

    // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
    nsRefPtr<ProfileDeinitResultHandler> res =
      new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));

    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
      sDeinitManager[i](res);
    }
  }

  BluetoothService::AcknowledgeToggleBt(sAdapterEnabled);

  if (sAdapterEnabled) {
    // Bluetooth just enabled, clear profile controllers and runnable arrays.
    sControllerArray.Clear();
    sChangeDiscoveryRunnableArray.Clear();
    sSetPropertyRunnableArray.Clear();
    sGetDeviceRunnableArray.Clear();
    sFetchUuidsRunnableArray.Clear();
    sBondingRunnableArray.Clear();
    sUnbondingRunnableArray.Clear();
    sPairingNameTable.Clear();

    // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., it should
    // be connectable and non-discoverable.
    NS_ENSURE_TRUE_VOID(sBtInterface);
    sBtInterface->SetAdapterProperty(
      BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
      new SetAdapterPropertyDiscoverableResultHandler());

    // Trigger BluetoothOppManager to listen
    BluetoothOppManager* opp = BluetoothOppManager::Get();
    if (!opp || !opp->Listen()) {
      BT_LOGR("Fail to start BluetoothOppManager listening");
    }
  }

  // Resolve promise if existed
  if (!sChangeAdapterStateRunnableArray.IsEmpty()) {
    DispatchReplySuccess(sChangeAdapterStateRunnableArray[0]);
    sChangeAdapterStateRunnableArray.RemoveElementAt(0);
  }
}