mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
Bug 1063877 - Change nsVolumeService to use sync IPC for initial request. r=khuey
This commit is contained in:
parent
ce68b1757c
commit
bc5e85d921
@ -147,6 +147,7 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsIVolume.h"
|
||||
#include "nsVolumeService.h"
|
||||
#include "nsIVolumeService.h"
|
||||
#include "SpeakerManagerService.h"
|
||||
using namespace mozilla::system;
|
||||
@ -2440,17 +2441,14 @@ ContentParent::RecvDataStoreGetStores(
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvBroadcastVolume(const nsString& aVolumeName)
|
||||
ContentParent::RecvGetVolumes(InfallibleTArray<VolumeInfo>* aResult)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
|
||||
if (vs) {
|
||||
vs->BroadcastVolume(aVolumeName);
|
||||
}
|
||||
nsRefPtr<nsVolumeService> vs = nsVolumeService::GetSingleton();
|
||||
vs->GetVolumesForIPC(aResult);
|
||||
return true;
|
||||
#else
|
||||
NS_WARNING("ContentParent::RecvBroadcastVolume shouldn't be called when MOZ_WIDGET_GONK is not defined");
|
||||
NS_WARNING("ContentParent::RecvGetVolumes shouldn't be called when MOZ_WIDGET_GONK is not defined");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ private:
|
||||
virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
|
||||
const bool& aHidden) MOZ_OVERRIDE;
|
||||
virtual bool RecvGetSystemMemory(const uint64_t& getterId) MOZ_OVERRIDE;
|
||||
virtual bool RecvBroadcastVolume(const nsString& aVolumeName) MOZ_OVERRIDE;
|
||||
virtual bool RecvGetVolumes(InfallibleTArray<VolumeInfo>* aResult) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDataStoreGetStores(
|
||||
const nsString& aName,
|
||||
|
@ -292,6 +292,19 @@ struct DataStoreSetting {
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
// Note: Any changes to this structure should also be changed in
|
||||
// FileSystemUpdate below.
|
||||
struct VolumeInfo {
|
||||
nsString name;
|
||||
nsString mountPoint;
|
||||
int32_t volState;
|
||||
int32_t mountGeneration;
|
||||
bool isMediaPresent;
|
||||
bool isSharing;
|
||||
bool isFormatting;
|
||||
bool isFake;
|
||||
};
|
||||
|
||||
intr protocol PContent
|
||||
{
|
||||
parent opens PCompositor;
|
||||
@ -428,6 +441,8 @@ child:
|
||||
FilePathUpdate(nsString storageType, nsString storageName, nsString filepath,
|
||||
nsCString reasons);
|
||||
|
||||
// Note: Any changes to this structure should also be changed in
|
||||
// VolumeInfo above.
|
||||
FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
|
||||
int32_t mountGeneration, bool isMediaPresent,
|
||||
bool isSharing, bool isFormatting, bool isFake);
|
||||
@ -620,8 +635,8 @@ parent:
|
||||
nsString aStorageName,
|
||||
nsString aFilepath,
|
||||
nsCString aReason);
|
||||
// get nsIVolumeService to broadcast volume information
|
||||
async BroadcastVolume(nsString volumeName);
|
||||
|
||||
sync GetVolumes() returns (VolumeInfo[] volumes);
|
||||
|
||||
// Notify the parent that the child has finished handling a system message.
|
||||
async SystemMessageHandled();
|
||||
|
@ -8,15 +8,13 @@
|
||||
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(cab99ab4-542e-4387-bd40-db6ef30e4f5f)]
|
||||
[scriptable, uuid(c31b182c-61a3-449c-bba8-fd45044499c2)]
|
||||
interface nsIVolumeService : nsISupports
|
||||
{
|
||||
nsIVolume getVolumeByName(in DOMString volName);
|
||||
nsIVolume getVolumeByPath(in DOMString path);
|
||||
nsIVolume createOrGetVolumeByPath(in DOMString path);
|
||||
|
||||
void BroadcastVolume(in DOMString volName);
|
||||
|
||||
nsIVolumeMountLock createMountLock(in DOMString volName);
|
||||
|
||||
nsIArray getVolumeNames();
|
||||
|
@ -65,18 +65,19 @@ nsresult nsVolumeMountLock::Init()
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, true /*weak*/);
|
||||
|
||||
// Request the sdcard info, so we know the state/generation without having
|
||||
// to wait for a state change.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
ContentChild::GetSingleton()->SendBroadcastVolume(mVolumeName);
|
||||
return NS_OK;
|
||||
}
|
||||
// Get the initial mountGeneration and grab a lock.
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
|
||||
|
||||
vs->BroadcastVolume(mVolumeName);
|
||||
nsCOMPtr<nsIVolume> vol;
|
||||
nsresult rv = vs->GetVolumeByName(mVolumeName, getter_AddRefs(vol));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = vol->GetMountGeneration(&mVolumeGeneration);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
return Lock(vol);
|
||||
}
|
||||
|
||||
/* void unlock (); */
|
||||
@ -142,12 +143,18 @@ NS_IMETHODIMP nsVolumeMountLock::Observe(nsISupports* aSubject, const char* aTop
|
||||
mWakeLock = nullptr;
|
||||
mVolumeGeneration = mountGeneration;
|
||||
|
||||
return Lock(vol);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsVolumeMountLock::Lock(nsIVolume* aVolume)
|
||||
{
|
||||
nsRefPtr<power::PowerManagerService> pmService =
|
||||
power::PowerManagerService::GetInstance();
|
||||
NS_ENSURE_TRUE(pmService, NS_ERROR_FAILURE);
|
||||
|
||||
nsString mountLockName;
|
||||
vol->GetMountLockName(mountLockName);
|
||||
aVolume->GetMountLockName(mountLockName);
|
||||
|
||||
ErrorResult err;
|
||||
mWakeLock = pmService->NewWakeLock(mountLockName, nullptr, err);
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsIVolume;
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
@ -41,6 +43,7 @@ private:
|
||||
~nsVolumeMountLock();
|
||||
|
||||
nsresult Init();
|
||||
nsresult Lock(nsIVolume* aVolume);
|
||||
|
||||
nsRefPtr<dom::WakeLock> mWakeLock;
|
||||
nsString mVolumeName;
|
||||
|
@ -86,13 +86,14 @@ nsVolumeService::Shutdown()
|
||||
}
|
||||
|
||||
nsVolumeService::nsVolumeService()
|
||||
: mArrayMonitor("nsVolumeServiceArray")
|
||||
: mArrayMonitor("nsVolumeServiceArray"),
|
||||
mGotVolumesFromParent(false)
|
||||
{
|
||||
sSingleton = this;
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
// Request the initial state for all volumes.
|
||||
ContentChild::GetSingleton()->SendBroadcastVolume(NS_LITERAL_STRING(""));
|
||||
// VolumeServiceIOThread and the WakeLock listener should only run in the
|
||||
// parent, so we return early.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -122,59 +123,10 @@ nsVolumeService::Callback(const nsAString& aTopic, const nsAString& aState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::BroadcastVolume(const nsAString& aVolName)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (aVolName.EqualsLiteral("")) {
|
||||
nsVolume::Array volumeArray;
|
||||
{
|
||||
// Copy the array since we don't want to call BroadcastVolume
|
||||
// while we're holding the lock.
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
volumeArray = mVolumeArray;
|
||||
}
|
||||
|
||||
// We treat being passed the empty string as "broadcast all volumes"
|
||||
nsVolume::Array::size_type numVolumes = volumeArray.Length();
|
||||
nsVolume::Array::index_type volIndex;
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
const nsString& volName(volumeArray[volIndex]->Name());
|
||||
if (!volName.EqualsLiteral("")) {
|
||||
// Note: The volume service is the only entity that should be able to
|
||||
// modify the array of volumes. So we shouldn't have any issues with
|
||||
// the array being modified under our feet (Since we're the volume
|
||||
// service the array can't change until after we finish iterating the
|
||||
// the loop).
|
||||
nsresult rv = BroadcastVolume(volName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<nsVolume> vol;
|
||||
{
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
vol = FindVolumeByName(aVolName);
|
||||
}
|
||||
if (!vol) {
|
||||
ERR("BroadcastVolume: Unable to locate volume '%s'",
|
||||
NS_LossyConvertUTF16toASCII(aVolName).get());
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, NS_NOINTERFACE);
|
||||
|
||||
DBG("nsVolumeService::BroadcastVolume for '%s'", vol->NameStr().get());
|
||||
NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
|
||||
obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVolume **aResult)
|
||||
{
|
||||
GetVolumesFromParent();
|
||||
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
|
||||
nsRefPtr<nsVolume> vol = FindVolumeByName(aVolName);
|
||||
@ -189,6 +141,8 @@ NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVol
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::GetVolumeByPath(const nsAString& aPath, nsIVolume **aResult)
|
||||
{
|
||||
GetVolumesFromParent();
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8Path(aPath);
|
||||
char realPathBuf[PATH_MAX];
|
||||
|
||||
@ -239,6 +193,8 @@ nsVolumeService::GetVolumeByPath(const nsAString& aPath, nsIVolume **aResult)
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::CreateOrGetVolumeByPath(const nsAString& aPath, nsIVolume** aResult)
|
||||
{
|
||||
GetVolumesFromParent();
|
||||
|
||||
nsresult rv = GetVolumeByPath(aPath, aResult);
|
||||
if (rv == NS_OK) {
|
||||
return NS_OK;
|
||||
@ -260,6 +216,8 @@ nsVolumeService::CreateOrGetVolumeByPath(const nsAString& aPath, nsIVolume** aRe
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::GetVolumeNames(nsIArray** aVolNames)
|
||||
{
|
||||
GetVolumesFromParent();
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aVolNames);
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
|
||||
@ -289,6 +247,60 @@ nsVolumeService::GetVolumeNames(nsIArray** aVolNames)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsVolumeService::GetVolumesForIPC(nsTArray<VolumeInfo>* aResult)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
|
||||
nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
|
||||
nsVolume::Array::index_type volIndex;
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
nsRefPtr<nsVolume> vol = mVolumeArray[volIndex];
|
||||
VolumeInfo* volInfo = aResult->AppendElement();
|
||||
|
||||
volInfo->name() = vol->mName;
|
||||
volInfo->mountPoint() = vol->mMountPoint;
|
||||
volInfo->volState() = vol->mState;
|
||||
volInfo->mountGeneration() = vol->mMountGeneration;
|
||||
volInfo->isMediaPresent() = vol->mIsMediaPresent;
|
||||
volInfo->isSharing() = vol->mIsSharing;
|
||||
volInfo->isFormatting() = vol->mIsFormatting;
|
||||
volInfo->isFake() = vol->mIsFake;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsVolumeService::GetVolumesFromParent()
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
// We are the parent. Therefore our volumes are already correct.
|
||||
return;
|
||||
}
|
||||
if (mGotVolumesFromParent) {
|
||||
// We've already done this, no need to do it again.
|
||||
return;
|
||||
}
|
||||
mGotVolumesFromParent = true;
|
||||
|
||||
nsTArray<VolumeInfo> result;
|
||||
ContentChild::GetSingleton()->SendGetVolumes(&result);
|
||||
for (uint32_t i = 0; i < result.Length(); i++) {
|
||||
const VolumeInfo& volInfo(result[i]);
|
||||
nsRefPtr<nsVolume> vol = new nsVolume(volInfo.name(),
|
||||
volInfo.mountPoint(),
|
||||
volInfo.volState(),
|
||||
volInfo.mountGeneration(),
|
||||
volInfo.isMediaPresent(),
|
||||
volInfo.isSharing(),
|
||||
volInfo.isFormatting(),
|
||||
volInfo.isFake());
|
||||
UpdateVolume(vol, false);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsVolumeService::CreateMountLock(const nsAString& aVolumeName, nsIVolumeMountLock **aResult)
|
||||
{
|
||||
@ -366,7 +378,7 @@ nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake /
|
||||
}
|
||||
|
||||
void
|
||||
nsVolumeService::UpdateVolume(nsIVolume* aVolume)
|
||||
nsVolumeService::UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -386,6 +398,11 @@ nsVolumeService::UpdateVolume(nsIVolume* aVolume)
|
||||
}
|
||||
|
||||
vol->Set(aVolume);
|
||||
|
||||
if (!aNotifyObservers) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
|
@ -15,6 +15,11 @@
|
||||
#include "nsVolume.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class VolumeInfo;
|
||||
} // dom
|
||||
|
||||
namespace system {
|
||||
|
||||
class WakeLockCallback;
|
||||
@ -40,9 +45,11 @@ public:
|
||||
//static nsVolumeService* GetSingleton();
|
||||
static void Shutdown();
|
||||
|
||||
void UpdateVolume(nsIVolume* aVolume);
|
||||
void UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers = true);
|
||||
void UpdateVolumeIOThread(const Volume* aVolume);
|
||||
|
||||
void GetVolumesForIPC(nsTArray<dom::VolumeInfo>* aResult);
|
||||
|
||||
private:
|
||||
~nsVolumeService();
|
||||
|
||||
@ -51,11 +58,13 @@ private:
|
||||
already_AddRefed<nsVolume> FindVolumeByMountLockName(const nsAString& aMountLockName);
|
||||
already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName);
|
||||
already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake = false);
|
||||
void GetVolumesFromParent();
|
||||
|
||||
Monitor mArrayMonitor;
|
||||
nsVolume::Array mVolumeArray;
|
||||
|
||||
static StaticRefPtr<nsVolumeService> sSingleton;
|
||||
bool mGotVolumesFromParent;
|
||||
};
|
||||
|
||||
} // system
|
||||
|
Loading…
x
Reference in New Issue
Block a user