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; }
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); } }
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(); }
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(); } }
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); }
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; }
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); }
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); } }