зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team a=merge
This commit is contained in:
Коммит
6bb9b2c074
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "e1773d6d1014c997be4b5c4233bba3ee073b8d7b",
|
||||
"git_revision": "42dc5f02a9df006b129824cd9bffa93cab937ab2",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "172680469094791e563268fa7d074fee9e0105ab",
|
||||
"revision": "1ada14e78334ed61c226ba43be1f3ac286c66a95",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e1773d6d1014c997be4b5c4233bba3ee073b8d7b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="42dc5f02a9df006b129824cd9bffa93cab937ab2"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -136,13 +136,3 @@ span#hostname {
|
|||
#automaticallyReportInFuture {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#reportSendingMessage {
|
||||
/* adjust the line-height to match the link */
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
#reportSentMessage {
|
||||
/* adjust the line-height to match the link */
|
||||
line-height: 22px;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "BatteryManager.h"
|
||||
#include "mozilla/dom/DeviceStorageAreaListener.h"
|
||||
#include "mozilla/dom/PowerManager.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
|
@ -210,6 +211,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
|||
#ifdef MOZ_EME
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager)
|
||||
#endif
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageAreaListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
@ -334,6 +336,10 @@ Navigator::Invalidate()
|
|||
mMediaKeySystemAccessManager = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mDeviceStorageAreaListener) {
|
||||
mDeviceStorageAreaListener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
@ -914,6 +920,20 @@ Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
|
|||
mWindow->GetOuterWindow());
|
||||
}
|
||||
|
||||
DeviceStorageAreaListener*
|
||||
Navigator::GetDeviceStorageAreaListener(ErrorResult& aRv)
|
||||
{
|
||||
if (!mDeviceStorageAreaListener) {
|
||||
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
mDeviceStorageAreaListener = new DeviceStorageAreaListener(mWindow);
|
||||
}
|
||||
|
||||
return mDeviceStorageAreaListener;
|
||||
}
|
||||
|
||||
nsDOMDeviceStorage*
|
||||
Navigator::GetDeviceStorage(const nsAString& aType, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -949,6 +969,28 @@ Navigator::GetDeviceStorages(const nsAString& aType,
|
|||
mDeviceStorageStores.AppendElements(aStores);
|
||||
}
|
||||
|
||||
nsDOMDeviceStorage*
|
||||
Navigator::GetDeviceStorageByNameAndType(const nsAString& aName,
|
||||
const nsAString& aType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<nsDOMDeviceStorage> storage;
|
||||
nsDOMDeviceStorage::CreateDeviceStorageByNameAndType(mWindow, aName, aType,
|
||||
getter_AddRefs(storage));
|
||||
|
||||
if (!storage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mDeviceStorageStores.AppendElement(storage);
|
||||
return storage;
|
||||
}
|
||||
|
||||
Geolocation*
|
||||
Navigator::GetGeolocation(ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ class Telephony;
|
|||
class Voicemail;
|
||||
class TVManager;
|
||||
class InputPortManager;
|
||||
class DeviceStorageAreaListener;
|
||||
|
||||
namespace time {
|
||||
class TimeManager;
|
||||
|
@ -214,11 +215,15 @@ public:
|
|||
void RemoveIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv);
|
||||
already_AddRefed<WakeLock> RequestWakeLock(const nsAString &aTopic,
|
||||
ErrorResult& aRv);
|
||||
DeviceStorageAreaListener* GetDeviceStorageAreaListener(ErrorResult& aRv);
|
||||
nsDOMDeviceStorage* GetDeviceStorage(const nsAString& aType,
|
||||
ErrorResult& aRv);
|
||||
void GetDeviceStorages(const nsAString& aType,
|
||||
nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores,
|
||||
ErrorResult& aRv);
|
||||
nsDOMDeviceStorage* GetDeviceStorageByNameAndType(const nsAString& aName,
|
||||
const nsAString& aType,
|
||||
ErrorResult& aRv);
|
||||
DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv);
|
||||
CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
|
||||
IccManager* GetMozIccManager(ErrorResult& aRv);
|
||||
|
@ -379,6 +384,7 @@ private:
|
|||
nsRefPtr<time::TimeManager> mTimeManager;
|
||||
nsRefPtr<ServiceWorkerContainer> mServiceWorkerContainer;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsRefPtr<DeviceStorageAreaListener> mDeviceStorageAreaListener;
|
||||
|
||||
// Hashtable for saving cached objects DoResolve created, so we don't create
|
||||
// the object twice if asked for it twice, whether due to use of "delete" or
|
||||
|
|
|
@ -512,7 +512,7 @@ Cache::CreatePushStream(nsIAsyncInputStream* aStream)
|
|||
NS_ASSERT_OWNINGTHREAD(Cache);
|
||||
MOZ_ASSERT(mActor);
|
||||
MOZ_ASSERT(aStream);
|
||||
return mActor->CreatePushStream(aStream);
|
||||
return mActor->CreatePushStream(this, aStream);
|
||||
}
|
||||
|
||||
Cache::~Cache()
|
||||
|
|
|
@ -73,11 +73,11 @@ CacheChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
|||
}
|
||||
|
||||
CachePushStreamChild*
|
||||
CacheChild::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
CacheChild::CreatePushStream(nsISupports* aParent, nsIAsyncInputStream* aStream)
|
||||
{
|
||||
mNumChildActors += 1;
|
||||
auto actor = SendPCachePushStreamConstructor(
|
||||
new CachePushStreamChild(GetFeature(), aStream));
|
||||
new CachePushStreamChild(GetFeature(), aParent, aStream));
|
||||
MOZ_ASSERT(actor);
|
||||
return static_cast<CachePushStreamChild*>(actor);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
nsISupports* aParent, const CacheOpArgs& aArgs);
|
||||
|
||||
CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream);
|
||||
CreatePushStream(nsISupports* aParent, nsIAsyncInputStream* aStream);
|
||||
|
||||
// Our parent Listener object has gone out of scope and is being destroyed.
|
||||
void StartDestroyFromListener();
|
||||
|
|
|
@ -93,10 +93,13 @@ NS_IMPL_ISUPPORTS(CachePushStreamChild::Callback, nsIInputStreamCallback,
|
|||
nsICancelableRunnable);
|
||||
|
||||
CachePushStreamChild::CachePushStreamChild(Feature* aFeature,
|
||||
nsISupports* aParent,
|
||||
nsIAsyncInputStream* aStream)
|
||||
: mStream(aStream)
|
||||
: mParent(aParent)
|
||||
, mStream(aStream)
|
||||
, mClosed(false)
|
||||
{
|
||||
MOZ_ASSERT(mParent);
|
||||
MOZ_ASSERT(mStream);
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
SetFeature(aFeature);
|
||||
|
|
|
@ -31,7 +31,8 @@ private:
|
|||
class Callback;
|
||||
|
||||
// This class must be constructed using CacheChild::CreatePushStream()
|
||||
CachePushStreamChild(Feature* aFeature, nsIAsyncInputStream* aStream);
|
||||
CachePushStreamChild(Feature* aFeature, nsISupports* aParent,
|
||||
nsIAsyncInputStream* aStream);
|
||||
~CachePushStreamChild();
|
||||
|
||||
// PCachePushStreamChild methods
|
||||
|
@ -46,6 +47,7 @@ private:
|
|||
|
||||
void OnEnd(nsresult aRv);
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsCOMPtr<nsIAsyncInputStream> mStream;
|
||||
nsRefPtr<Callback> mCallback;
|
||||
bool mClosed;
|
||||
|
|
|
@ -292,6 +292,12 @@ public:
|
|||
const nsAString& aType,
|
||||
nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores);
|
||||
|
||||
static void
|
||||
CreateDeviceStorageByNameAndType(nsPIDOMWindow* aWin,
|
||||
const nsAString& aName,
|
||||
const nsAString& aType,
|
||||
nsDOMDeviceStorage** aStore);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
static void GetOrderedVolumeNames(nsTArray<nsString>& aVolumeNames);
|
||||
|
@ -334,6 +340,11 @@ private:
|
|||
already_AddRefed<nsDOMDeviceStorage>
|
||||
GetStorageByName(const nsAString &aStorageName);
|
||||
|
||||
static already_AddRefed<nsDOMDeviceStorage>
|
||||
GetStorageByNameAndType(nsPIDOMWindow* aWin,
|
||||
const nsAString& aStorageName,
|
||||
const nsAString& aType);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
bool mIsWatchingFile;
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/DeviceStorageAreaListener.h"
|
||||
#include "mozilla/dom/DeviceStorageAreaListenerBinding.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class VolumeStateObserver final : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
explicit VolumeStateObserver(DeviceStorageAreaListener* aListener)
|
||||
: mDeviceStorageAreaListener(aListener) {}
|
||||
void ForgetListener() { mDeviceStorageAreaListener = nullptr; }
|
||||
|
||||
private:
|
||||
~VolumeStateObserver() {};
|
||||
|
||||
// This reference is non-owning and it's cleared by
|
||||
// DeviceStorageAreaListener's destructor.
|
||||
DeviceStorageAreaListener* MOZ_NON_OWNING_REF mDeviceStorageAreaListener;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(VolumeStateObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
VolumeStateObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
if (!mDeviceStorageAreaListener) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
|
||||
nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
|
||||
MOZ_ASSERT(vol);
|
||||
|
||||
int32_t state;
|
||||
nsresult rv = vol->GetState(&state);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsString volName;
|
||||
vol->GetName(volName);
|
||||
|
||||
switch (state) {
|
||||
case nsIVolume::STATE_MOUNTED:
|
||||
mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent(
|
||||
volName,
|
||||
DeviceStorageAreaChangedEventOperation::Added);
|
||||
break;
|
||||
default:
|
||||
mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent(
|
||||
volName,
|
||||
DeviceStorageAreaChangedEventOperation::Removed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(DeviceStorageAreaListener)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
DeviceStorageAreaListener::DeviceStorageAreaListener(nsPIDOMWindow* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
mVolumeStateObserver = new VolumeStateObserver(this);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DeviceStorageAreaListener::~DeviceStorageAreaListener()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED);
|
||||
}
|
||||
#endif
|
||||
mVolumeStateObserver->ForgetListener();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DeviceStorageAreaListener::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return DeviceStorageAreaListenerBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
DeviceStorageAreaListener::DispatchStorageAreaChangedEvent(
|
||||
const nsString& aStorageName,
|
||||
DeviceStorageAreaChangedEventOperation aOperation)
|
||||
{
|
||||
StateMapType::const_iterator iter = mStorageAreaStateMap.find(aStorageName);
|
||||
if (iter == mStorageAreaStateMap.end() &&
|
||||
aOperation != DeviceStorageAreaChangedEventOperation::Added) {
|
||||
// The operation of the first event to dispatch should be "Added".
|
||||
return;
|
||||
}
|
||||
if (iter != mStorageAreaStateMap.end() &&
|
||||
iter->second == aOperation) {
|
||||
// No need to disptach the event if the state is unchanged.
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceStorageAreaChangedEventInit init;
|
||||
init.mOperation = aOperation;
|
||||
init.mStorageName = aStorageName;
|
||||
|
||||
nsRefPtr<DeviceStorageAreaChangedEvent> event =
|
||||
DeviceStorageAreaChangedEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("storageareachanged"),
|
||||
init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
bool ignore;
|
||||
DOMEventTargetHelper::DispatchEvent(event, &ignore);
|
||||
|
||||
mStorageAreaStateMap[aStorageName] = aOperation;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_DeviceStorageAreaListener_h
|
||||
#define mozilla_dom_DeviceStorageAreaListener_h
|
||||
|
||||
#include <map>
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/DeviceStorageAreaChangedEvent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class VolumeStateObserver;
|
||||
|
||||
class DeviceStorageAreaListener final : public DOMEventTargetHelper
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
IMPL_EVENT_HANDLER(storageareachanged)
|
||||
|
||||
explicit DeviceStorageAreaListener(nsPIDOMWindow* aWindow);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
friend class VolumeStateObserver;
|
||||
|
||||
typedef std::map<nsString, DeviceStorageAreaChangedEventOperation> StateMapType;
|
||||
StateMapType mStorageAreaStateMap;
|
||||
|
||||
nsRefPtr<VolumeStateObserver> mVolumeStateObserver;
|
||||
|
||||
~DeviceStorageAreaListener();
|
||||
|
||||
void DispatchStorageAreaChangedEvent(
|
||||
const nsString& aStorageName,
|
||||
DeviceStorageAreaChangedEventOperation aOperation);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_DeviceStorageAreaListener_h
|
|
@ -2,6 +2,7 @@
|
|||
"runtests":{
|
||||
},
|
||||
"excludetests":{
|
||||
"dom/devicestorage/test/test_dirs.html":"excluded"
|
||||
"dom/devicestorage/test/test_dirs.html":"excluded",
|
||||
"dom/devicestorage/test/test_storageAreaListener.html":"excluded"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,17 @@ EXPORTS += [
|
|||
'nsDeviceStorage.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'DeviceStorageAreaListener.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom.devicestorage += [
|
||||
'DeviceStorageRequestChild.h',
|
||||
'DeviceStorageRequestParent.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'DeviceStorageAreaListener.cpp',
|
||||
'DeviceStorageRequestChild.cpp',
|
||||
'DeviceStorageRequestParent.cpp',
|
||||
'nsDeviceStorage.cpp',
|
||||
|
|
|
@ -3579,6 +3579,30 @@ nsDOMDeviceStorage::CreateDeviceStoragesFor(
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsDOMDeviceStorage::CreateDeviceStorageByNameAndType(
|
||||
nsPIDOMWindow* aWin,
|
||||
const nsAString& aName,
|
||||
const nsAString& aType,
|
||||
nsDOMDeviceStorage** aStore)
|
||||
{
|
||||
if (!DeviceStorageTypeChecker::IsVolumeBased(aType)) {
|
||||
nsRefPtr<nsDOMDeviceStorage> storage = new nsDOMDeviceStorage(aWin);
|
||||
if (NS_FAILED(storage->Init(aWin, aType, EmptyString()))) {
|
||||
*aStore = nullptr;
|
||||
return;
|
||||
}
|
||||
NS_ADDREF(*aStore = storage.get());
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsDOMDeviceStorage> storage = GetStorageByNameAndType(aWin,
|
||||
aName,
|
||||
aType);
|
||||
NS_ADDREF(*aStore = storage.get());
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsDOMDeviceStorage::ParseFullPath(const nsAString& aFullPath,
|
||||
|
@ -3638,14 +3662,28 @@ nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName)
|
|||
ds = this;
|
||||
return ds.forget();
|
||||
}
|
||||
|
||||
return GetStorageByNameAndType(GetOwner(), aStorageName, mStorageType);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsDOMDeviceStorage>
|
||||
nsDOMDeviceStorage::GetStorageByNameAndType(nsPIDOMWindow* aWin,
|
||||
const nsAString& aStorageName,
|
||||
const nsAString& aType)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<nsDOMDeviceStorage> ds;
|
||||
|
||||
VolumeNameArray volNames;
|
||||
GetOrderedVolumeNames(volNames);
|
||||
VolumeNameArray::size_type numVolumes = volNames.Length();
|
||||
VolumeNameArray::index_type i;
|
||||
for (i = 0; i < numVolumes; i++) {
|
||||
if (volNames[i].Equals(aStorageName)) {
|
||||
ds = new nsDOMDeviceStorage(GetOwner());
|
||||
nsresult rv = ds->Init(GetOwner(), mStorageType, aStorageName);
|
||||
ds = new nsDOMDeviceStorage(aWin);
|
||||
nsresult rv = ds->Init(aWin, aType, aStorageName);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ support-files = devicestorage_common.js
|
|||
[test_usedSpace.html]
|
||||
[test_watch.html]
|
||||
[test_watchOther.html]
|
||||
[test_storageAreaListener.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
|
||||
# FileSystem API tests
|
||||
[test_fs_basic.html]
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1126694
|
||||
-->
|
||||
<head>
|
||||
<title>Test for device storage area listener API </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="devicestorage_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1126694">Mozilla Bug 1126684</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
devicestorage_setup()
|
||||
|
||||
var XPCOMUtils = SpecialPowers.Cu.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
|
||||
var volumeService = SpecialPowers.Cc["@mozilla.org/telephony/volume-service;1"].getService(Ci.nsIVolumeService);
|
||||
|
||||
var volName = "dummy-volume";
|
||||
var mountPoint = "/data/local/tmp/dummy";
|
||||
|
||||
var storage;
|
||||
if (navigator.deviceStorageAreaListener) {
|
||||
ok (true, "got deviceStorageAreaListener")
|
||||
}
|
||||
|
||||
navigator.deviceStorageAreaListener.addEventListener("storageareachanged", function (e) {
|
||||
info("got storageareachanged event name:" + e.storageName + "\n");
|
||||
info("operation:" + e.operation + "\n");
|
||||
|
||||
if (e.operation == "added") {
|
||||
storage = navigator.getDeviceStorageByNameAndType(e.storageName, "sdcard");
|
||||
ok (storage, "got storage");
|
||||
volumeService.removeFakeVolume(volName);
|
||||
}
|
||||
else if (e.operation == "removed") {
|
||||
ok (true, "got removal event");
|
||||
devicestorage_cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
volumeService.createFakeVolume(volName, mountPoint);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -2361,6 +2361,21 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvVolumeRemoved(const nsString& aFsName)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsRefPtr<nsVolumeService> vs = nsVolumeService::GetSingleton();
|
||||
if (vs) {
|
||||
vs->RemoveVolumeByName(aFsName);
|
||||
}
|
||||
#else
|
||||
// Remove warnings about unused arguments
|
||||
unused << aFsName;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvNotifyProcessPriorityChanged(
|
||||
const hal::ProcessPriority& aPriority)
|
||||
|
|
|
@ -360,6 +360,7 @@ public:
|
|||
const bool& aIsUnmounting,
|
||||
const bool& aIsRemovable,
|
||||
const bool& aIsHotSwappable) override;
|
||||
virtual bool RecvVolumeRemoved(const nsString& aFsName) override;
|
||||
|
||||
virtual bool RecvNuwaFork() override;
|
||||
|
||||
|
|
|
@ -654,6 +654,7 @@ static const char* sObserverTopics[] = {
|
|||
"file-watcher-update",
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_VOLUME_STATE_CHANGED,
|
||||
NS_VOLUME_REMOVED,
|
||||
"phone-state-changed",
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
|
@ -3166,6 +3167,15 @@ ContentParent::Observe(nsISupports* aSubject,
|
|||
nsString state(aData);
|
||||
unused << SendNotifyPhoneStateChange(state);
|
||||
}
|
||||
else if(!strcmp(aTopic, NS_VOLUME_REMOVED)) {
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!(IsNuwaReady() && IsNuwaProcess()))
|
||||
#endif
|
||||
{
|
||||
nsString volName(aData);
|
||||
unused << SendVolumeRemoved(volName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
// Make sure accessibility is running in content process when accessibility
|
||||
|
@ -4561,6 +4571,22 @@ ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsS
|
|||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvRemoveFakeVolume(const nsString& fsName)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
|
||||
if (vs) {
|
||||
vs->RemoveFakeVolume(fsName);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
NS_WARNING("ContentParent::RecvRemoveFakeVolume shouldn't be called when MOZ_WIDGET_GONK is not defined");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvKeywordToURI(const nsCString& aKeyword,
|
||||
nsString* aProviderName,
|
||||
|
|
|
@ -787,6 +787,8 @@ private:
|
|||
|
||||
virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) override;
|
||||
|
||||
virtual bool RecvRemoveFakeVolume(const nsString& fsName) override;
|
||||
|
||||
virtual bool RecvKeywordToURI(const nsCString& aKeyword,
|
||||
nsString* aProviderName,
|
||||
OptionalInputStreamParams* aPostData,
|
||||
|
|
|
@ -574,6 +574,9 @@ child:
|
|||
bool isSharing, bool isFormatting, bool isFake,
|
||||
bool isUnmounting, bool isRemovable, bool isHotSwappable);
|
||||
|
||||
// Notify volume is removed.
|
||||
VolumeRemoved(nsString fsName);
|
||||
|
||||
// Ask the Nuwa process to create a new child process.
|
||||
NuwaFork();
|
||||
|
||||
|
@ -898,6 +901,7 @@ parent:
|
|||
// called by the child (test code only) to propagate volume changes to the parent
|
||||
async CreateFakeVolume(nsString fsName, nsString mountPoint);
|
||||
async SetFakeVolumeState(nsString fsName, int32_t fsState);
|
||||
async RemoveFakeVolume(nsString fsName);
|
||||
|
||||
sync KeywordToURI(nsCString keyword)
|
||||
returns (nsString providerName, OptionalInputStreamParams postData, OptionalURIParams uri);
|
||||
|
|
|
@ -38,15 +38,13 @@ typedef android::MediaCodecProxy MediaCodecProxy;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
GonkAudioDecoderManager::GonkAudioDecoderManager(
|
||||
MediaTaskQueue* aTaskQueue,
|
||||
const AudioInfo& aConfig)
|
||||
: GonkDecoderManager(aTaskQueue)
|
||||
, mAudioChannels(aConfig.mChannels)
|
||||
GonkAudioDecoderManager::GonkAudioDecoderManager(const AudioInfo& aConfig)
|
||||
: mAudioChannels(aConfig.mChannels)
|
||||
, mAudioRate(aConfig.mRate)
|
||||
, mAudioProfile(aConfig.mProfile)
|
||||
, mUseAdts(true)
|
||||
, mAudioBuffer(nullptr)
|
||||
, mMonitor("GonkAudioDecoderManager")
|
||||
{
|
||||
MOZ_COUNT_CTOR(GonkAudioDecoderManager);
|
||||
MOZ_ASSERT(mAudioChannels);
|
||||
|
@ -111,13 +109,53 @@ GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback)
|
|||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkAudioDecoderManager::SendSampleToOMX(MediaRawData* aSample)
|
||||
bool
|
||||
GonkAudioDecoderManager::HasQueuedSample()
|
||||
{
|
||||
return mDecoder->Input(reinterpret_cast<const uint8_t*>(aSample->mData),
|
||||
aSample->mSize,
|
||||
aSample->mTime,
|
||||
0);
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
return mQueueSample.Length();
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkAudioDecoderManager::Input(MediaRawData* aSample)
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
nsRefPtr<MediaRawData> sample;
|
||||
|
||||
if (aSample) {
|
||||
sample = aSample;
|
||||
if (!PerformFormatSpecificProcess(sample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// It means EOS with empty sample.
|
||||
sample = new MediaRawData();
|
||||
}
|
||||
|
||||
mQueueSample.AppendElement(sample);
|
||||
|
||||
status_t rv;
|
||||
while (mQueueSample.Length()) {
|
||||
nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
|
||||
{
|
||||
MonitorAutoUnlock mon_exit(mMonitor);
|
||||
rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->mData),
|
||||
data->mSize,
|
||||
data->mTime,
|
||||
0);
|
||||
}
|
||||
if (rv == OK) {
|
||||
mQueueSample.RemoveElementAt(0);
|
||||
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
|
||||
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
|
||||
// buffer on time.
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -182,6 +220,21 @@ GonkAudioDecoderManager::CreateAudioData(int64_t aStreamOffset, AudioData **v) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkAudioDecoderManager::Flush()
|
||||
{
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mQueueSample.Clear();
|
||||
}
|
||||
|
||||
if (mDecoder->flush() != OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkAudioDecoderManager::Output(int64_t aStreamOffset,
|
||||
nsRefPtr<MediaData>& aOutData)
|
||||
|
@ -258,15 +311,4 @@ void GonkAudioDecoderManager::ReleaseAudioBuffer() {
|
|||
mAudioBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkAudioDecoderManager::Flush()
|
||||
{
|
||||
GonkDecoderManager::Flush();
|
||||
status_t err = mDecoder->flush();
|
||||
if (err != OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -23,30 +23,28 @@ namespace mozilla {
|
|||
class GonkAudioDecoderManager : public GonkDecoderManager {
|
||||
typedef android::MediaCodecProxy MediaCodecProxy;
|
||||
public:
|
||||
GonkAudioDecoderManager(MediaTaskQueue* aTaskQueue,
|
||||
const AudioInfo& aConfig);
|
||||
~GonkAudioDecoderManager();
|
||||
GonkAudioDecoderManager(const AudioInfo& aConfig);
|
||||
|
||||
virtual ~GonkAudioDecoderManager() override;
|
||||
|
||||
virtual android::sp<MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) override;
|
||||
|
||||
virtual nsresult Input(MediaRawData* aSample) override;
|
||||
|
||||
virtual nsresult Output(int64_t aStreamOffset,
|
||||
nsRefPtr<MediaData>& aOutput) override;
|
||||
|
||||
virtual nsresult Flush() override;
|
||||
|
||||
protected:
|
||||
virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) override;
|
||||
|
||||
virtual status_t SendSampleToOMX(MediaRawData* aSample) override;
|
||||
virtual bool HasQueuedSample() override;
|
||||
|
||||
private:
|
||||
bool PerformFormatSpecificProcess(MediaRawData* aSample);
|
||||
|
||||
nsresult CreateAudioData(int64_t aStreamOffset,
|
||||
AudioData** aOutData);
|
||||
|
||||
void ReleaseAudioBuffer();
|
||||
// MediaCodedc's wrapper that performs the decoding.
|
||||
android::sp<MediaCodecProxy> mDecoder;
|
||||
|
||||
const uint32_t mAudioChannels;
|
||||
const uint32_t mAudioRate;
|
||||
|
@ -56,6 +54,17 @@ private:
|
|||
MediaDataDecoderCallback* mReaderCallback;
|
||||
android::MediaBuffer* mAudioBuffer;
|
||||
android::sp<ALooper> mLooper;
|
||||
|
||||
// MediaCodedc's wrapper that performs the decoding.
|
||||
android::sp<android::MediaCodecProxy> mDecoder;
|
||||
|
||||
// This monitor protects mQueueSample.
|
||||
Monitor mMonitor;
|
||||
|
||||
// An queue with the MP4 samples which are waiting to be sent into OMX.
|
||||
// If an element is an empty MP4Sample, that menas EOS. There should not
|
||||
// any sample be queued after EOS.
|
||||
nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -34,8 +34,7 @@ GonkDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
|
|||
MediaDataDecoderCallback* aCallback)
|
||||
{
|
||||
nsRefPtr<MediaDataDecoder> decoder =
|
||||
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aVideoTaskQueue,
|
||||
aImageContainer, aConfig),
|
||||
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aImageContainer, aConfig),
|
||||
aVideoTaskQueue, aCallback);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
@ -46,7 +45,7 @@ GonkDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig,
|
|||
MediaDataDecoderCallback* aCallback)
|
||||
{
|
||||
nsRefPtr<MediaDataDecoder> decoder =
|
||||
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aAudioTaskQueue, aConfig),
|
||||
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig),
|
||||
aAudioTaskQueue, aCallback);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
|
|
@ -25,58 +25,6 @@ using namespace android;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
GonkDecoderManager::GonkDecoderManager(MediaTaskQueue* aTaskQueue)
|
||||
: mMonitor("GonkDecoderManager")
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkDecoderManager::Input(MediaRawData* aSample)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
nsRefPtr<MediaRawData> sample;
|
||||
|
||||
if (!aSample) {
|
||||
// It means EOS with empty sample.
|
||||
sample = new MediaRawData();
|
||||
} else {
|
||||
sample = aSample;
|
||||
if (!PerformFormatSpecificProcess(sample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
mQueueSample.AppendElement(sample);
|
||||
|
||||
status_t rv;
|
||||
while (mQueueSample.Length()) {
|
||||
nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
|
||||
{
|
||||
ReentrantMonitorAutoExit mon_exit(mMonitor);
|
||||
rv = SendSampleToOMX(data);
|
||||
}
|
||||
if (rv == OK) {
|
||||
mQueueSample.RemoveElementAt(0);
|
||||
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
|
||||
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
|
||||
// buffer on time.
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkDecoderManager::Flush()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
mQueueSample.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
|
||||
FlushableMediaTaskQueue* aTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback)
|
||||
|
|
|
@ -19,8 +19,6 @@ class MediaRawData;
|
|||
// Manage the data flow from inputting encoded data and outputting decode data.
|
||||
class GonkDecoderManager {
|
||||
public:
|
||||
GonkDecoderManager(MediaTaskQueue* aTaskQueue);
|
||||
|
||||
virtual ~GonkDecoderManager() {}
|
||||
|
||||
// Creates and initializs the GonkDecoder.
|
||||
|
@ -28,7 +26,7 @@ public:
|
|||
virtual android::sp<android::MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) = 0;
|
||||
|
||||
// Add samples into OMX decoder or queue them if decoder is out of input buffer.
|
||||
virtual nsresult Input(MediaRawData* aSample);
|
||||
virtual nsresult Input(MediaRawData* aSample) = 0;
|
||||
|
||||
// Produces decoded output, it blocks until output can be produced or a timeout
|
||||
// is expired or until EOS. Returns NS_OK on success, or NS_ERROR_NOT_AVAILABLE
|
||||
|
@ -40,32 +38,12 @@ public:
|
|||
nsRefPtr<MediaData>& aOutput) = 0;
|
||||
|
||||
// Flush the queued sample.
|
||||
// It this function is overrided by subclass, this functino should be called
|
||||
// in the overrided function.
|
||||
virtual nsresult Flush();
|
||||
virtual nsresult Flush() = 0;
|
||||
|
||||
// It should be called in MediaTask thread.
|
||||
bool HasQueuedSample() {
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
return mQueueSample.Length();
|
||||
}
|
||||
// True if sample is queued.
|
||||
virtual bool HasQueuedSample() = 0;
|
||||
|
||||
protected:
|
||||
// It performs special operation to MP4 sample, the real action is depended on
|
||||
// the codec type.
|
||||
virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) { return true; }
|
||||
|
||||
// It sends MP4Sample to OMX layer. It must be overrided by subclass.
|
||||
virtual android::status_t SendSampleToOMX(MediaRawData* aSample) = 0;
|
||||
|
||||
// This monitor protects mQueueSample.
|
||||
ReentrantMonitor mMonitor;
|
||||
|
||||
// An queue with the MP4 samples which are waiting to be sent into OMX.
|
||||
// If an element is an empty MP4Sample, that menas EOS. There should not
|
||||
// any sample be queued after EOS.
|
||||
nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
|
||||
|
||||
nsRefPtr<MediaByteBuffer> mCodecSpecificData;
|
||||
|
||||
nsAutoCString mMimeType;
|
||||
|
|
|
@ -44,16 +44,15 @@ typedef android::MediaCodecProxy MediaCodecProxy;
|
|||
namespace mozilla {
|
||||
|
||||
GonkVideoDecoderManager::GonkVideoDecoderManager(
|
||||
MediaTaskQueue* aTaskQueue,
|
||||
mozilla::layers::ImageContainer* aImageContainer,
|
||||
const VideoInfo& aConfig)
|
||||
: GonkDecoderManager(aTaskQueue)
|
||||
, mImageContainer(aImageContainer)
|
||||
: mImageContainer(aImageContainer)
|
||||
, mReaderCallback(nullptr)
|
||||
, mLastDecodedTime(0)
|
||||
, mColorConverterBufferSize(0)
|
||||
, mNativeWindow(nullptr)
|
||||
, mPendingVideoBuffersLock("GonkVideoDecoderManager::mPendingVideoBuffersLock")
|
||||
, mMonitor("GonkVideoDecoderManager")
|
||||
{
|
||||
MOZ_COUNT_CTOR(GonkVideoDecoderManager);
|
||||
mMimeType = aConfig.mMimeType;
|
||||
|
@ -117,6 +116,52 @@ GonkVideoDecoderManager::Init(MediaDataDecoderCallback* aCallback)
|
|||
return mDecoder;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkVideoDecoderManager::Input(MediaRawData* aSample)
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
nsRefPtr<MediaRawData> sample;
|
||||
|
||||
if (!aSample) {
|
||||
// It means EOS with empty sample.
|
||||
sample = new MediaRawData();
|
||||
} else {
|
||||
sample = aSample;
|
||||
}
|
||||
|
||||
mQueueSample.AppendElement(sample);
|
||||
|
||||
status_t rv;
|
||||
while (mQueueSample.Length()) {
|
||||
nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
|
||||
{
|
||||
MonitorAutoUnlock mon_unlock(mMonitor);
|
||||
rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->mData),
|
||||
data->mSize,
|
||||
data->mTime,
|
||||
0);
|
||||
}
|
||||
if (rv == OK) {
|
||||
mQueueSample.RemoveElementAt(0);
|
||||
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
|
||||
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
|
||||
// buffer on time.
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
GonkVideoDecoderManager::HasQueuedSample()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
return mQueueSample.Length();
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
|
||||
{
|
||||
|
@ -305,6 +350,23 @@ GonkVideoDecoderManager::SetVideoFormat()
|
|||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkVideoDecoderManager::Flush()
|
||||
{
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mQueueSample.Clear();
|
||||
}
|
||||
|
||||
mLastDecodedTime = 0;
|
||||
|
||||
if (mDecoder->flush() != OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Blocks until decoded sample is produced by the deoder.
|
||||
nsresult
|
||||
GonkVideoDecoderManager::Output(int64_t aStreamOffset,
|
||||
|
@ -393,27 +455,6 @@ void GonkVideoDecoderManager::ReleaseVideoBuffer() {
|
|||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
GonkVideoDecoderManager::SendSampleToOMX(MediaRawData* aSample)
|
||||
{
|
||||
return mDecoder->Input(reinterpret_cast<const uint8_t*>(aSample->mData),
|
||||
aSample->mSize,
|
||||
aSample->mTime,
|
||||
0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkVideoDecoderManager::Flush()
|
||||
{
|
||||
GonkDecoderManager::Flush();
|
||||
mLastDecodedTime = 0;
|
||||
status_t err = mDecoder->flush();
|
||||
if (err != OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GonkVideoDecoderManager::codecReserved()
|
||||
{
|
||||
|
@ -574,12 +615,4 @@ void GonkVideoDecoderManager::ReleaseAllPendingVideoBuffers()
|
|||
releasingVideoBuffers.clear();
|
||||
}
|
||||
|
||||
void GonkVideoDecoderManager::ReleaseMediaResources() {
|
||||
GVDM_LOG("ReleseMediaResources");
|
||||
if (mDecoder == nullptr) {
|
||||
return;
|
||||
}
|
||||
ReleaseAllPendingVideoBuffers();
|
||||
mDecoder->ReleaseMediaResources();
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -38,26 +38,24 @@ typedef android::MediaCodecProxy MediaCodecProxy;
|
|||
typedef mozilla::layers::TextureClient TextureClient;
|
||||
|
||||
public:
|
||||
GonkVideoDecoderManager(MediaTaskQueue* aTaskQueue,
|
||||
mozilla::layers::ImageContainer* aImageContainer,
|
||||
GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer,
|
||||
const VideoInfo& aConfig);
|
||||
|
||||
~GonkVideoDecoderManager();
|
||||
virtual ~GonkVideoDecoderManager() override;
|
||||
|
||||
virtual android::sp<MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) override;
|
||||
|
||||
virtual nsresult Input(MediaRawData* aSample) override;
|
||||
|
||||
virtual nsresult Output(int64_t aStreamOffset,
|
||||
nsRefPtr<MediaData>& aOutput) override;
|
||||
|
||||
virtual nsresult Flush() override;
|
||||
|
||||
virtual void ReleaseMediaResources();
|
||||
virtual bool HasQueuedSample() override;
|
||||
|
||||
static void RecycleCallback(TextureClient* aClient, void* aClosure);
|
||||
|
||||
protected:
|
||||
virtual android::status_t SendSampleToOMX(MediaRawData* aSample) override;
|
||||
|
||||
private:
|
||||
struct FrameInfo
|
||||
{
|
||||
|
@ -129,7 +127,6 @@ private:
|
|||
nsIntRect mPicture;
|
||||
nsIntSize mInitialFrame;
|
||||
|
||||
android::sp<MediaCodecProxy> mDecoder;
|
||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||
|
||||
android::MediaBuffer* mVideoBuffer;
|
||||
|
@ -160,6 +157,16 @@ private:
|
|||
// The lock protects mPendingVideoBuffers.
|
||||
Mutex mPendingVideoBuffersLock;
|
||||
|
||||
// MediaCodedc's wrapper that performs the decoding.
|
||||
android::sp<android::MediaCodecProxy> mDecoder;
|
||||
|
||||
// This monitor protects mQueueSample.
|
||||
Monitor mMonitor;
|
||||
|
||||
// An queue with the MP4 samples which are waiting to be sent into OMX.
|
||||
// If an element is an empty MP4Sample, that menas EOS. There should not
|
||||
// any sample be queued after EOS.
|
||||
nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -101,6 +101,7 @@ interface nsIVolume : nsISupports
|
|||
%{C++
|
||||
// For use with the ObserverService
|
||||
#define NS_VOLUME_STATE_CHANGED "volume-state-changed"
|
||||
#define NS_VOLUME_REMOVED "volume-removed"
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(879874c6-5532-437a-bf76-703d0c2e7e77)]
|
||||
[scriptable, uuid(cfbf9880-cba5-11e4-8830-0800200c9a66)]
|
||||
interface nsIVolumeService : nsISupports
|
||||
{
|
||||
nsIVolume getVolumeByName(in DOMString volName);
|
||||
|
@ -24,6 +24,9 @@ interface nsIVolumeService : nsISupports
|
|||
/* for test case only to simulate sdcard insertion/removal */
|
||||
void createFakeVolume(in DOMString name, in DOMString path);
|
||||
void SetFakeVolumeState(in DOMString name, in long state);
|
||||
|
||||
/* for test case only to test removal of storage area */
|
||||
void removeFakeVolume(in DOMString name);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
|
|
@ -439,7 +439,7 @@ NS_IMETHODIMP
|
|||
nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT,
|
||||
nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_MOUNTED,
|
||||
-1 /* mountGeneration */,
|
||||
true /* isMediaPresent */,
|
||||
false /* isSharing */,
|
||||
|
@ -469,9 +469,15 @@ nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
|
|||
if (!vol || !vol->IsFake()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
vol->SetState(state);
|
||||
vol->LogState();
|
||||
UpdateVolume(vol.get());
|
||||
|
||||
// UpdateVolume expects the volume passed in to NOT be the
|
||||
// same pointer as what CreateOrFindVolumeByName would return,
|
||||
// which is why we allocate a temporary volume here.
|
||||
nsRefPtr<nsVolume> volume = new nsVolume(name);
|
||||
volume->Set(vol);
|
||||
volume->SetState(state);
|
||||
volume->LogState();
|
||||
UpdateVolume(volume.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -479,6 +485,41 @@ nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::RemoveFakeVolume(const nsAString& name)
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
SetFakeVolumeState(name, nsIVolume::STATE_NOMEDIA);
|
||||
RemoveVolumeByName(name);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ContentChild::GetSingleton()->SendRemoveFakeVolume(nsString(name));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsVolumeService::RemoveVolumeByName(const nsAString& aName)
|
||||
{
|
||||
nsRefPtr<nsVolume> vol;
|
||||
{
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
vol = FindVolumeByName(aName);
|
||||
}
|
||||
if (!vol) {
|
||||
return;
|
||||
}
|
||||
mVolumeArray.RemoveElement(vol);
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
obs->NotifyObservers(nullptr, NS_VOLUME_REMOVED, nsString(aName).get());
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* The UpdateVolumeRunnable creates an nsVolume and updates the main thread
|
||||
* data structure while running on the main thread.
|
||||
|
|
|
@ -46,12 +46,15 @@ public:
|
|||
|
||||
void DumpNoLock(const char* aLabel);
|
||||
|
||||
// To use this function, you have to create a new volume and pass it in.
|
||||
void UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers = true);
|
||||
void UpdateVolumeIOThread(const Volume* aVolume);
|
||||
|
||||
void RecvVolumesFromParent(const nsTArray<dom::VolumeInfo>& aVolumes);
|
||||
void GetVolumesForIPC(nsTArray<dom::VolumeInfo>* aResult);
|
||||
|
||||
void RemoveVolumeByName(const nsAString& aName);
|
||||
|
||||
private:
|
||||
~nsVolumeService();
|
||||
|
||||
|
|
|
@ -342,6 +342,8 @@ var interfaceNamesInGlobalScope =
|
|||
"DeviceProximityEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DeviceStorageAreaChangedEvent", desktop: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DeviceStorageAreaListener", desktop: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DeviceStorage", desktop: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
[Pref="device.storage.enabled"]
|
||||
interface DeviceStorageAreaListener : EventTarget {
|
||||
// Fired when a storage area is added or removed.
|
||||
attribute EventHandler onstorageareachanged;
|
||||
};
|
|
@ -245,12 +245,19 @@ partial interface Navigator {
|
|||
MozWakeLock requestWakeLock(DOMString aTopic);
|
||||
};
|
||||
|
||||
partial interface Navigator {
|
||||
[Throws, Pref="device.storage.enabled"]
|
||||
readonly attribute DeviceStorageAreaListener deviceStorageAreaListener;
|
||||
};
|
||||
|
||||
// nsIDOMNavigatorDeviceStorage
|
||||
partial interface Navigator {
|
||||
[Throws, Pref="device.storage.enabled"]
|
||||
DeviceStorage? getDeviceStorage(DOMString type);
|
||||
[Throws, Pref="device.storage.enabled"]
|
||||
sequence<DeviceStorage> getDeviceStorages(DOMString type);
|
||||
[Throws, Pref="device.storage.enabled"]
|
||||
DeviceStorage? getDeviceStorageByNameAndType(DOMString name, DOMString type);
|
||||
};
|
||||
|
||||
// nsIDOMNavigatorDesktopNotification
|
||||
|
|
|
@ -103,6 +103,7 @@ WEBIDL_FILES = [
|
|||
'DesktopNotification.webidl',
|
||||
'DeviceMotionEvent.webidl',
|
||||
'DeviceStorage.webidl',
|
||||
'DeviceStorageAreaListener.webidl',
|
||||
'Directory.webidl',
|
||||
'DisplayPortInputPort.webidl',
|
||||
'Document.webidl',
|
||||
|
|
|
@ -224,6 +224,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
|||
AutoCancel autoCancel(this);
|
||||
|
||||
if (!aValue.isObject()) {
|
||||
NS_WARNING("FetchEvent::RespondWith was passed a promise resolved to a non-Object value");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,11 @@ TextureClient*
|
|||
D3D11ShareHandleImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
RefPtr<TextureClientD3D11> textureClient =
|
||||
new TextureClientD3D11(aClient->GetForwarder(),
|
||||
mFormat,
|
||||
TextureFlags::DEFAULT);
|
||||
textureClient->InitWith(mTexture, mSize);
|
||||
mTextureClient = textureClient;
|
||||
mTextureClient = TextureClientD3D11::Create(aClient->GetForwarder(),
|
||||
mFormat,
|
||||
TextureFlags::DEFAULT,
|
||||
mTexture,
|
||||
mSize);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -202,12 +202,12 @@ D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
|
|||
{
|
||||
EnsureSynchronized();
|
||||
if (!mTextureClient) {
|
||||
RefPtr<SharedTextureClientD3D9> textureClient =
|
||||
new SharedTextureClientD3D9(aClient->GetForwarder(),
|
||||
gfx::SurfaceFormat::B8G8R8X8,
|
||||
TextureFlags::DEFAULT);
|
||||
textureClient->InitWith(mTexture, mShareHandle, mDesc);
|
||||
mTextureClient = textureClient;
|
||||
mTextureClient = SharedTextureClientD3D9::Create(aClient->GetForwarder(),
|
||||
gfx::SurfaceFormat::B8G8R8X8,
|
||||
TextureFlags::DEFAULT,
|
||||
mTexture,
|
||||
mShareHandle,
|
||||
mDesc);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -190,12 +190,17 @@ IMFYCbCrImage::GetD3D9TextureClient(CompositableClient* aClient)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DXGIYCbCrTextureClient> texClient =
|
||||
new DXGIYCbCrTextureClient(aClient->GetForwarder(), TextureFlags::DEFAULT);
|
||||
texClient->InitWith(textureY, textureCb, textureCr,
|
||||
shareHandleY, shareHandleCb, shareHandleCr,
|
||||
GetSize(), mData.mYSize, mData.mCbCrSize);
|
||||
mTextureClient = texClient;
|
||||
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY,
|
||||
textureCb,
|
||||
textureCr,
|
||||
shareHandleY,
|
||||
shareHandleCb,
|
||||
shareHandleCr,
|
||||
GetSize(),
|
||||
mData.mYSize,
|
||||
mData.mCbCrSize);
|
||||
|
||||
return mTextureClient;
|
||||
}
|
||||
|
@ -268,12 +273,17 @@ IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
|
|||
textureCr->QueryInterface((IDXGIResource**)byRef(resource));
|
||||
hr = resource->GetSharedHandle(&shareHandleCr);
|
||||
|
||||
RefPtr<DXGIYCbCrTextureClient> texClient =
|
||||
new DXGIYCbCrTextureClient(aClient->GetForwarder(), TextureFlags::DEFAULT);
|
||||
texClient->InitWith(textureY, textureCb, textureCr,
|
||||
shareHandleY, shareHandleCb, shareHandleCr,
|
||||
GetSize(), mData.mYSize, mData.mCbCrSize);
|
||||
mTextureClient = texClient;
|
||||
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY,
|
||||
textureCb,
|
||||
textureCr,
|
||||
shareHandleY,
|
||||
shareHandleCb,
|
||||
shareHandleCr,
|
||||
GetSize(),
|
||||
mData.mYSize,
|
||||
mData.mCbCrSize);
|
||||
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,9 @@ TextureClient*
|
|||
MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
RefPtr<MacIOSurfaceTextureClientOGL> buffer =
|
||||
new MacIOSurfaceTextureClientOGL(aClient->GetForwarder(), TextureFlags::DEFAULT);
|
||||
buffer->InitWith(mSurface);
|
||||
mTextureClient = buffer;
|
||||
mTextureClient = MacIOSurfaceTextureClientOGL::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
mSurface);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -1318,6 +1318,10 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtr<AsyncPanZoomControll
|
|||
continue;
|
||||
}
|
||||
|
||||
// Guard against a possible infinite-loop condition. If we hit this, the
|
||||
// layout code that generates the handoff parents did something wrong.
|
||||
MOZ_ASSERT(apzc->GetScrollHandoffParentId() != apzc->GetGuid().mScrollId);
|
||||
|
||||
// Find the AsyncPanZoomController instance with a matching layersId and
|
||||
// the scroll id that matches apzc->GetScrollHandoffParentId(). To do this
|
||||
// search the subtree with the same layersId for the apzc with the specified
|
||||
|
|
|
@ -212,6 +212,22 @@ TextureClientD3D11::~TextureClientD3D11()
|
|||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
TemporaryRef<TextureClientD3D11>
|
||||
TextureClientD3D11::Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize)
|
||||
{
|
||||
RefPtr<TextureClientD3D11> texture = new TextureClientD3D11(aAllocator,
|
||||
aFormat,
|
||||
aFlags);
|
||||
texture->mTexture = aTexture;
|
||||
texture->mSize = aSize;
|
||||
return texture;
|
||||
}
|
||||
|
||||
TemporaryRef<TextureClient>
|
||||
TextureClientD3D11::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
|
@ -534,6 +550,34 @@ DXGIYCbCrTextureClient::~DXGIYCbCrTextureClient()
|
|||
MOZ_COUNT_DTOR(DXGIYCbCrTextureClient);
|
||||
}
|
||||
|
||||
// static
|
||||
TemporaryRef<DXGIYCbCrTextureClient>
|
||||
DXGIYCbCrTextureClient::Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
IUnknown* aTextureY,
|
||||
IUnknown* aTextureCb,
|
||||
IUnknown* aTextureCr,
|
||||
HANDLE aHandleY,
|
||||
HANDLE aHandleCb,
|
||||
HANDLE aHandleCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr)
|
||||
{
|
||||
RefPtr<DXGIYCbCrTextureClient> texture =
|
||||
new DXGIYCbCrTextureClient(aAllocator, aFlags);
|
||||
texture->mHandles[0] = aHandleY;
|
||||
texture->mHandles[1] = aHandleCb;
|
||||
texture->mHandles[2] = aHandleCr;
|
||||
texture->mHoldRefs[0] = aTextureY;
|
||||
texture->mHoldRefs[1] = aTextureCb;
|
||||
texture->mHoldRefs[2] = aTextureCr;
|
||||
texture->mSize = aSize;
|
||||
texture->mSizeY = aSizeY;
|
||||
texture->mSizeCbCr = aSizeCbCr;
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool
|
||||
DXGIYCbCrTextureClient::Lock(OpenMode)
|
||||
{
|
||||
|
|
|
@ -32,11 +32,13 @@ public:
|
|||
|
||||
virtual ~TextureClientD3D11();
|
||||
|
||||
void InitWith(ID3D11Texture2D* aTexture, const gfx::IntSize& aSize)
|
||||
{
|
||||
mTexture = aTexture;
|
||||
mSize = aSize;
|
||||
}
|
||||
// Creates a TextureClient and init width.
|
||||
static TemporaryRef<TextureClientD3D11>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
// TextureClient
|
||||
|
||||
|
@ -90,6 +92,20 @@ public:
|
|||
|
||||
virtual ~DXGIYCbCrTextureClient();
|
||||
|
||||
// Creates a TextureClient and init width.
|
||||
static TemporaryRef<DXGIYCbCrTextureClient>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
IUnknown* aTextureY,
|
||||
IUnknown* aTextureCb,
|
||||
IUnknown* aTextureCr,
|
||||
HANDLE aHandleY,
|
||||
HANDLE aHandleCb,
|
||||
HANDLE aHandleCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override{ return !!mHoldRefs[0]; }
|
||||
|
@ -102,27 +118,6 @@ public:
|
|||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
void InitWith(IUnknown* aTextureY,
|
||||
IUnknown* aTextureCb,
|
||||
IUnknown* aTextureCr,
|
||||
HANDLE aHandleY,
|
||||
HANDLE aHandleCb,
|
||||
HANDLE aHandleCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr)
|
||||
{
|
||||
mHandles[0] = aHandleY;
|
||||
mHandles[1] = aHandleCb;
|
||||
mHandles[2] = aHandleCr;
|
||||
mHoldRefs[0] = aTextureY;
|
||||
mHoldRefs[1] = aTextureCb;
|
||||
mHoldRefs[2] = aTextureCr;
|
||||
mSize = aSize;
|
||||
mSizeY = aSizeY;
|
||||
mSizeCbCr = aSizeCbCr;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const
|
||||
{
|
||||
return mSize;
|
||||
|
|
|
@ -762,6 +762,29 @@ SharedTextureClientD3D9::~SharedTextureClientD3D9()
|
|||
MOZ_COUNT_DTOR(SharedTextureClientD3D9);
|
||||
}
|
||||
|
||||
// static
|
||||
TemporaryRef<SharedTextureClientD3D9>
|
||||
SharedTextureClientD3D9::Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DTexture9* aTexture,
|
||||
HANDLE aSharedHandle,
|
||||
D3DSURFACE_DESC aDesc)
|
||||
{
|
||||
RefPtr<SharedTextureClientD3D9> texture =
|
||||
new SharedTextureClientD3D9(aAllocator,
|
||||
aFormat,
|
||||
aFlags);
|
||||
MOZ_ASSERT(!texture->mTexture);
|
||||
texture->mTexture = aTexture;
|
||||
texture->mHandle = aSharedHandle;
|
||||
texture->mDesc = aDesc;
|
||||
if (texture->mTexture) {
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed += texture->mDesc.Width * texture->mDesc.Height * 4;
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedTextureClientD3D9::Lock(OpenMode)
|
||||
{
|
||||
|
|
|
@ -248,6 +248,15 @@ public:
|
|||
|
||||
virtual ~SharedTextureClientD3D9();
|
||||
|
||||
// Creates a TextureClient and init width.
|
||||
static TemporaryRef<SharedTextureClientD3D9>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DTexture9* aTexture,
|
||||
HANDLE aSharedHandle,
|
||||
D3DSURFACE_DESC aDesc);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return !!mTexture; }
|
||||
|
@ -260,17 +269,6 @@ public:
|
|||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
void InitWith(IDirect3DTexture9* aTexture, HANDLE aSharedHandle, D3DSURFACE_DESC aDesc)
|
||||
{
|
||||
MOZ_ASSERT(!mTexture);
|
||||
mTexture = aTexture;
|
||||
mHandle = aSharedHandle;
|
||||
mDesc = aDesc;
|
||||
if (mTexture) {
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed += mDesc.Width * mDesc.Height * 4;
|
||||
}
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mDesc.Width, mDesc.Height);
|
||||
|
|
|
@ -59,16 +59,6 @@ GrallocTextureClientOGL::CreateSimilar(TextureFlags aFlags,
|
|||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle, gfx::IntSize aSize)
|
||||
{
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
MOZ_ASSERT(IsValid());
|
||||
mGrallocHandle = aHandle;
|
||||
mGraphicBuffer = GetGraphicBufferFrom(aHandle);
|
||||
mSize = aSize;
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
|
|
|
@ -60,8 +60,6 @@ public:
|
|||
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
|
||||
|
||||
void InitWith(MaybeMagicGrallocBufferHandle aDesc, gfx::IntSize aSize);
|
||||
|
||||
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
|
||||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
|
|
@ -22,12 +22,18 @@ MacIOSurfaceTextureClientOGL::~MacIOSurfaceTextureClientOGL()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureClientOGL::InitWith(MacIOSurface* aSurface)
|
||||
// static
|
||||
TemporaryRef<MacIOSurfaceTextureClientOGL>
|
||||
MacIOSurfaceTextureClientOGL::Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
MacIOSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mSurface = aSurface;
|
||||
RefPtr<MacIOSurfaceTextureClientOGL> texture =
|
||||
new MacIOSurfaceTextureClientOGL(aAllocator, aFlags);
|
||||
MOZ_ASSERT(texture->IsValid());
|
||||
MOZ_ASSERT(!texture->IsAllocated());
|
||||
texture->mSurface = aSurface;
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -21,7 +21,11 @@ public:
|
|||
|
||||
virtual ~MacIOSurfaceTextureClientOGL();
|
||||
|
||||
void InitWith(MacIOSurface* aSurface);
|
||||
// Creates a TextureClient and init width.
|
||||
static TemporaryRef<MacIOSurfaceTextureClientOGL>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
MacIOSurface* aSurface);
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
|
|
|
@ -8186,6 +8186,10 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have the scrollparent being the same as the scroll id, the
|
||||
// compositor-side code could get into an infinite loop while building the
|
||||
// overscroll handoff chain.
|
||||
MOZ_ASSERT(aScrollParentId == FrameMetrics::NULL_SCROLL_ID || scrollId != aScrollParentId);
|
||||
metrics.SetScrollId(scrollId);
|
||||
metrics.SetIsRoot(aIsRoot);
|
||||
metrics.SetScrollParentId(aScrollParentId);
|
||||
|
|
|
@ -485,10 +485,11 @@ FontFace::ParseDescriptor(nsCSSFontDesc aDescID,
|
|||
nsCOMPtr<nsIPrincipal> principal = global->PrincipalOrNull();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mParent);
|
||||
nsCOMPtr<nsIURI> docURI = window->GetDocumentURI();
|
||||
nsCOMPtr<nsIURI> base = window->GetDocBaseURI();
|
||||
|
||||
if (!parser.ParseFontFaceDescriptor(aDescID, aString,
|
||||
nullptr, // aSheetURL
|
||||
docURI, // aSheetURL
|
||||
base,
|
||||
principal,
|
||||
aResult)) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
var f = new FontFace("x", "url(x.ttf)", { unicodeRange: "U+0041" });
|
||||
f.load();
|
||||
document.fonts.add(f);
|
||||
f = new FontFace("x", "url(x.ttf)", { unicodeRange: "U+0042" });
|
||||
f.load();
|
||||
</script>
|
|
@ -113,5 +113,6 @@ load 1074651-1.html
|
|||
pref(dom.webcomponents.enabled,true) load 1089463-1.html
|
||||
pref(layout.css.expensive-style-struct-assertions.enabled,true) load 1136010-1.html
|
||||
load 1153693-1.html
|
||||
load 1161366-1.html
|
||||
load large_border_image_width.html
|
||||
load border-image-visited-link.html
|
||||
|
|
|
@ -827,8 +827,8 @@ input[type=range] {
|
|||
display: inline-block;
|
||||
inline-size: 12em;
|
||||
block-size: 1.3em;
|
||||
margin-inline-start: 0.7em;
|
||||
margin-inline-end: 0.7em;
|
||||
-moz-margin-start: 0.7em;
|
||||
-moz-margin-end: 0.7em;
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0;
|
||||
/* Override some rules that apply on all input types: */
|
||||
|
@ -843,8 +843,8 @@ input[type=range] {
|
|||
input[type=range][orient=block] {
|
||||
inline-size: 1.3em;
|
||||
block-size: 12em;
|
||||
margin-inline-start: 0;
|
||||
margin-inline-end: 0;
|
||||
-moz-margin-start: 0;
|
||||
-moz-margin-end: 0;
|
||||
margin-block-start: 0.7em;
|
||||
margin-block-end: 0.7em;
|
||||
}
|
||||
|
|
|
@ -2611,7 +2611,12 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
|
|||
parentdata_ = maybeFakeParentData.ptr(); \
|
||||
} \
|
||||
} \
|
||||
if (aStartStruct) \
|
||||
if (eStyleStruct_##type_ == eStyleStruct_Variables) \
|
||||
/* no need to copy construct an nsStyleVariables, as we will copy */ \
|
||||
/* inherited variables (and set canStoreInRuleTree to false) in */ \
|
||||
/* ComputeVariablesData */ \
|
||||
data_ = new (mPresContext) nsStyle##type_ ctorargs_; \
|
||||
else if (aStartStruct) \
|
||||
/* We only need to compute the delta between this computed data and */ \
|
||||
/* our computed data. */ \
|
||||
data_ = new (mPresContext) \
|
||||
|
|
|
@ -3643,6 +3643,7 @@ nsStyleVariables::nsStyleVariables()
|
|||
nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleVariables);
|
||||
mVariables = aSource.mVariables;
|
||||
}
|
||||
|
||||
nsStyleVariables::~nsStyleVariables(void)
|
||||
|
|
|
@ -1300,7 +1300,7 @@ int WebrtcVideoConduit::SendRTCPPacket(int channel, const void* data, int len)
|
|||
CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__);
|
||||
return len;
|
||||
} else if(mTransmitterTransport &&
|
||||
(mTransmitterTransport->SendRtpPacket(data, len) == NS_OK)) {
|
||||
(mTransmitterTransport->SendRtcpPacket(data, len) == NS_OK)) {
|
||||
CSFLogDebug(logTag, "%s Sent RTCP Packet (sender report) ", __FUNCTION__);
|
||||
return len;
|
||||
} else {
|
||||
|
|
|
@ -401,7 +401,6 @@ xul|textbox[disabled="true"] {
|
|||
html|a,
|
||||
.text-link,
|
||||
.inline-link {
|
||||
line-height: 22px;
|
||||
color: #0095dd;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak,
|
|||
|
||||
// handle the no conversion case
|
||||
if (nsCRT::strcmp(aSrcBreak, aDestBreak) == 0) {
|
||||
resultString = (T*)moz_xmalloc(sizeof(T) * aIoLen);
|
||||
resultString = (T*)malloc(sizeof(T) * aIoLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak,
|
|||
// handle the easy case, where the string length does not change, and the
|
||||
// breaks are only 1 char long, i.e. CR <-> LF
|
||||
if (srcBreakLen == destBreakLen && srcBreakLen == 1) {
|
||||
resultString = (T*)moz_xmalloc(sizeof(T) * aIoLen);
|
||||
resultString = (T*)malloc(sizeof(T) * aIoLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak,
|
|||
|
||||
int32_t newBufLen =
|
||||
aIoLen - (numLinebreaks * srcBreakLen) + (numLinebreaks * destBreakLen);
|
||||
resultString = (T*)moz_xmalloc(sizeof(T) * newBufLen);
|
||||
resultString = (T*)malloc(sizeof(T) * newBufLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ ConvertUnknownBreaks(const T* aInSrc, int32_t& aIoLen, const char* aDestBreak)
|
|||
src++;
|
||||
}
|
||||
|
||||
T* resultString = (T*)moz_xmalloc(sizeof(T) * finalLen);
|
||||
T* resultString = (T*)malloc(sizeof(T) * finalLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -853,6 +853,10 @@ nsresult
|
|||
NS_CloneInputStream(nsIInputStream* aSource, nsIInputStream** aCloneOut,
|
||||
nsIInputStream** aReplacementOut)
|
||||
{
|
||||
if (NS_WARN_IF(!aSource)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Attempt to perform the clone directly on the source stream
|
||||
nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(aSource);
|
||||
if (cloneable && cloneable->GetCloneable()) {
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
|
||||
TEST(CloneInputStream, InvalidInput)
|
||||
{
|
||||
nsCOMPtr<nsIInputStream> clone;
|
||||
nsresult rv = NS_CloneInputStream(nullptr, getter_AddRefs(clone));
|
||||
ASSERT_TRUE(NS_FAILED(rv));
|
||||
ASSERT_FALSE(clone);
|
||||
}
|
||||
|
||||
TEST(CloneInputStream, CloneableInput)
|
||||
{
|
||||
nsTArray<char> inputData;
|
||||
|
|
Загрузка…
Ссылка в новой задаче