mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Back out 6737ce4d3ce6:599c37ed628c (bug 785124) for b2g Arm xpcshell orange in update tests
This commit is contained in:
parent
c4574bd3fa
commit
69566d191b
@ -11,27 +11,12 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const XRE_OS_UPDATE_APPLY_TO_DIR = "OSUpdApplyToD"
|
||||
const UPDATE_ARCHIVE_DIR = "UpdArchD"
|
||||
const LOCAL_DIR = "/data/local";
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "env",
|
||||
"@mozilla.org/process/environment;1",
|
||||
"nsIEnvironment");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "volumeService",
|
||||
"@mozilla.org/telephony/volume-service;1",
|
||||
"nsIVolumeService");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gExtStorage", function dp_gExtStorage() {
|
||||
return Services.env.get("EXTERNAL_STORAGE");
|
||||
});
|
||||
|
||||
const VERBOSE = 1;
|
||||
let log =
|
||||
VERBOSE ?
|
||||
function log_dump(msg) { dump("DirectoryProvider: " + msg + "\n"); } :
|
||||
function log_noop(msg) { };
|
||||
|
||||
function DirectoryProvider() {
|
||||
}
|
||||
|
||||
@ -50,148 +35,36 @@ DirectoryProvider.prototype = {
|
||||
file.initWithPath(LOCAL_DIR);
|
||||
persistent.value = true;
|
||||
return file;
|
||||
}
|
||||
if (prop == "coreAppsDir") {
|
||||
} else if (prop == "coreAppsDir") {
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
|
||||
file.initWithPath("/system/b2g");
|
||||
persistent.value = true;
|
||||
return file;
|
||||
}
|
||||
if (prop == XRE_OS_UPDATE_APPLY_TO_DIR ||
|
||||
prop == UPDATE_ARCHIVE_DIR) {
|
||||
let file = this.getUpdateDir(persistent);
|
||||
return file;
|
||||
} else if (prop == XRE_OS_UPDATE_APPLY_TO_DIR) {
|
||||
return this.getOSUpdateApplyToDir(persistent);
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
},
|
||||
|
||||
// The VolumeService only exists on the device, and not on desktop
|
||||
volumeHasFreeSpace: function dp_volumeHasFreeSpace(volumePath, requiredSpace) {
|
||||
if (!volumePath) {
|
||||
return false;
|
||||
}
|
||||
if (!Services.volumeService) {
|
||||
return false;
|
||||
}
|
||||
let volume = Services.volumeService.getVolumeByPath(volumePath);
|
||||
if (!volume || volume.state !== Ci.nsIVolume.STATE_MOUNTED) {
|
||||
return false;
|
||||
}
|
||||
let stat = volume.getStats();
|
||||
if (!stat) {
|
||||
return false;
|
||||
}
|
||||
return requiredSpace <= stat.freeBytes;
|
||||
},
|
||||
|
||||
findUpdateDirWithFreeSpace: function dp_findUpdateDirWithFreeSpace(requiredSpace) {
|
||||
if (!Services.volumeService) {
|
||||
return this.createUpdatesDir(LOCAL_DIR);
|
||||
}
|
||||
let activeUpdate = Services.um.activeUpdate;
|
||||
if (this.volumeHasFreeSpace(gExtStorage, requiredSpace)) {
|
||||
let extUpdateDir = this.createUpdatesDir(gExtStorage);
|
||||
if (extUpdateDir !== null) {
|
||||
return extUpdateDir;
|
||||
}
|
||||
log("Warning: " + gExtStorage + " has enough free space for update " +
|
||||
activeUpdate.name + ", but is not writable");
|
||||
}
|
||||
|
||||
if (this.volumeHasFreeSpace(LOCAL_DIR, requiredSpace)) {
|
||||
let localUpdateDir = this.createUpdatesDir(LOCAL_DIR);
|
||||
if (localUpdateDir !== null) {
|
||||
return localUpdateDir;
|
||||
}
|
||||
log("Warning: " + LOCAL_DIR + " has enough free space for update " +
|
||||
activeUpdate.name + ", but is not writable");
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
getUpdateDir: function dp_getUpdateDir(persistent) {
|
||||
let defaultUpdateDir = this.getDefaultUpdateDir();
|
||||
persistent.value = false;
|
||||
getOSUpdateApplyToDir: function dp_getOSUpdateApplyToDir(persistent) {
|
||||
// TODO add logic to check available storage space,
|
||||
// and iterate through pref(s) to find alternative dirs if
|
||||
// necessary.
|
||||
|
||||
let activeUpdate = Services.um.activeUpdate;
|
||||
if (!activeUpdate) {
|
||||
log("Warning: No active update found, using default update dir: " +
|
||||
defaultUpdateDir);
|
||||
return defaultUpdateDir;
|
||||
}
|
||||
|
||||
let selectedPatch = activeUpdate.selectedPatch;
|
||||
if (!selectedPatch) {
|
||||
log("Warning: No selected patch, using default update dir: " +
|
||||
defaultUpdateDir);
|
||||
return defaultUpdateDir;
|
||||
}
|
||||
|
||||
let requiredSpace = selectedPatch.size * 2;
|
||||
let updateDir = this.findUpdateDirWithFreeSpace(requiredSpace, persistent);
|
||||
if (updateDir) {
|
||||
return updateDir;
|
||||
}
|
||||
|
||||
// If we've gotten this far, there isn't enough free space to download the patch
|
||||
// on either external storage or /data/local. All we can do is report the
|
||||
// error and let upstream code handle it more gracefully.
|
||||
log("Error: No volume found with " + requiredSpace + " bytes for downloading"+
|
||||
" update " + activeUpdate.name);
|
||||
throw Cr.NS_ERROR_FILE_TOO_BIG;
|
||||
},
|
||||
|
||||
createUpdatesDir: function dp_createUpdatesDir(root) {
|
||||
let dir = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
dir.initWithPath(root);
|
||||
if (!dir.isWritable()) {
|
||||
return null;
|
||||
}
|
||||
dir.appendRelativePath("updates/0");
|
||||
if (dir.exists()) {
|
||||
if (dir.isDirectory() && dir.isWritable()) {
|
||||
return dir;
|
||||
}
|
||||
// updates/0 is either a file or isn't writable. In either case we
|
||||
// can't use it.
|
||||
log("Error: " + dir.path + " is a file or isn't writable");
|
||||
return null;
|
||||
}
|
||||
// updates/0 doesn't exist, and the parent is writable, so try to
|
||||
// create it. This can fail if a file named updates exists.
|
||||
try {
|
||||
dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0770);
|
||||
} catch (e) {
|
||||
// The create failed for some reason. We can't use it.
|
||||
log("Error: " + dir.path + " unable to create directory");
|
||||
return null;
|
||||
}
|
||||
return dir;
|
||||
},
|
||||
|
||||
getDefaultUpdateDir: function dp_getDefaultUpdateDir() {
|
||||
let path = gExtStorage;
|
||||
let path = Services.env.get("EXTERNAL_STORAGE");
|
||||
if (!path) {
|
||||
path = LOCAL_DIR;
|
||||
}
|
||||
|
||||
if (Services.volumeService) {
|
||||
let extVolume = Services.volumeService.getVolumeByPath(path);
|
||||
if (!extVolume) {
|
||||
path = LOCAL_DIR;
|
||||
}
|
||||
path = LOCAL_PATH;
|
||||
}
|
||||
|
||||
let dir = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile)
|
||||
dir.initWithPath(path);
|
||||
|
||||
if (!dir.exists() && path != LOCAL_DIR) {
|
||||
// Fallback to LOCAL_DIR if we didn't fallback earlier
|
||||
dir.initWithPath(LOCAL_DIR);
|
||||
if (!dir.exists() && path != LOCAL_PATH) {
|
||||
// Fallback to LOCAL_PATH if we didn't fallback earlier
|
||||
dir.initWithPath(LOCAL_PATH);
|
||||
|
||||
if (!dir.exists()) {
|
||||
throw Cr.NS_ERROR_FILE_NOT_FOUND;
|
||||
@ -199,6 +72,7 @@ DirectoryProvider.prototype = {
|
||||
}
|
||||
|
||||
dir.appendRelativePath("updates");
|
||||
persistent.value = false;
|
||||
return dir;
|
||||
}
|
||||
};
|
||||
|
@ -22,9 +22,6 @@ const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout";
|
||||
const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout";
|
||||
|
||||
const NETWORK_ERROR_OFFLINE = 111;
|
||||
const FILE_ERROR_TOO_BIG = 112;
|
||||
|
||||
const STATE_DOWNLOADING = 'downloading';
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "aus",
|
||||
"@mozilla.org/updates/update-service;1",
|
||||
@ -275,17 +272,8 @@ UpdatePrompt.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
let status = Services.aus.downloadUpdate(aUpdate, true);
|
||||
if (status == STATE_DOWNLOADING) {
|
||||
Services.aus.addDownloadListener(this);
|
||||
return;
|
||||
}
|
||||
|
||||
log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
|
||||
if (aUpdate.errorCode == FILE_ERROR_TOO_BIG) {
|
||||
aUpdate.statusText = "file-too-big";
|
||||
}
|
||||
this.showUpdateError(aUpdate);
|
||||
Services.aus.downloadUpdate(aUpdate, true);
|
||||
Services.aus.addDownloadListener(this);
|
||||
},
|
||||
|
||||
handleDownloadCancel: function UP_handleDownloadCancel() {
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "mozilla/layers/PCompositorChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIMemoryInfoDumper.h"
|
||||
@ -102,7 +101,6 @@
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
using namespace base;
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::docshell;
|
||||
using namespace mozilla::dom::bluetooth;
|
||||
using namespace mozilla::dom::devicestorage;
|
||||
@ -1085,24 +1083,14 @@ ContentChild::RecvFilePathUpdate(const nsString& type, const nsString& path, con
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
|
||||
const nsString& aName,
|
||||
const int32_t& aState,
|
||||
const int32_t& aMountGeneration)
|
||||
ContentChild::RecvFileSystemUpdate(const nsString& aFsName, const nsString& aName, const int32_t &aState)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsRefPtr<nsVolume> volume = new nsVolume(aFsName, aName, aState,
|
||||
aMountGeneration);
|
||||
nsRefPtr<nsVolume> volume = new nsVolume(aFsName, aName, aState);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
nsString stateStr(NS_ConvertUTF8toUTF16(volume->StateStr()));
|
||||
obs->NotifyObservers(volume, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
#else
|
||||
// Remove warnings about unused arguments
|
||||
unused << aFsName;
|
||||
unused << aName;
|
||||
unused << aState;
|
||||
unused << aMountGeneration;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -183,10 +183,7 @@ public:
|
||||
virtual bool RecvLastPrivateDocShellDestroyed();
|
||||
|
||||
virtual bool RecvFilePathUpdate(const nsString& type, const nsString& path, const nsCString& reason);
|
||||
virtual bool RecvFileSystemUpdate(const nsString& aFsName,
|
||||
const nsString& aName,
|
||||
const int32_t& aState,
|
||||
const int32_t& aMountGeneration);
|
||||
virtual bool RecvFileSystemUpdate(const nsString& aFsName, const nsString& aName, const int32_t& aState);
|
||||
|
||||
#ifdef ANDROID
|
||||
gfxIntSize GetScreenSize() { return mScreenSize; }
|
||||
|
@ -102,7 +102,6 @@
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
using namespace mozilla::system;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_BT
|
||||
@ -236,9 +235,9 @@ ContentParent::MaybeTakePreallocatedAppProcess()
|
||||
/*static*/ void
|
||||
ContentParent::FirstIdle(void)
|
||||
{
|
||||
// The parent has gone idle for the first time. This would be a good
|
||||
// time to preallocate an app process.
|
||||
ScheduleDelayedPreallocateAppProcess();
|
||||
// The parent has gone idle for the first time. This would be a good
|
||||
// time to preallocate an app process.
|
||||
ScheduleDelayedPreallocateAppProcess();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@ -1134,22 +1133,6 @@ ContentParent::RecvAudioChannelUnregisterType(const AudioChannelType& aType)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvBroadcastVolume(const nsString& aVolumeName)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
|
||||
if (vs) {
|
||||
vs->BroadcastVolume(aVolumeName);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
NS_WARNING("ContentParent::RecvBroadcastVolume shouldn't be called when MOZ_WIDGET_GONK is not defined");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS3(ContentParent,
|
||||
nsIObserver,
|
||||
nsIThreadObserver,
|
||||
@ -1229,15 +1212,12 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
nsString volName;
|
||||
nsString mountPoint;
|
||||
int32_t state;
|
||||
int32_t mountGeneration;
|
||||
|
||||
vol->GetName(volName);
|
||||
vol->GetMountPoint(mountPoint);
|
||||
vol->GetState(&state);
|
||||
vol->GetMountGeneration(&mountGeneration);
|
||||
|
||||
unused << SendFileSystemUpdate(volName, mountPoint, state,
|
||||
mountGeneration);
|
||||
unused << SendFileSystemUpdate(volName, mountPoint, state);
|
||||
}
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
|
@ -326,8 +326,6 @@ private:
|
||||
virtual bool RecvAudioChannelRegisterType(const AudioChannelType& aType);
|
||||
virtual bool RecvAudioChannelUnregisterType(const AudioChannelType& aType);
|
||||
|
||||
virtual bool RecvBroadcastVolume(const nsString& aVolumeName);
|
||||
|
||||
virtual void ProcessingError(Result what) MOZ_OVERRIDE;
|
||||
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
|
@ -327,8 +327,7 @@ child:
|
||||
|
||||
FilePathUpdate(nsString type, nsString filepath, nsCString reasons);
|
||||
|
||||
FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
|
||||
int32_t mountGeneration);
|
||||
FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState);
|
||||
|
||||
parent:
|
||||
/**
|
||||
@ -440,9 +439,6 @@ parent:
|
||||
async AudioChannelRegisterType(AudioChannelType aType);
|
||||
async AudioChannelUnregisterType(AudioChannelType aType);
|
||||
|
||||
// get nsIVolumeService to broadcast volume information
|
||||
async BroadcastVolume(nsString volumeName);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ static const nsDependentCString sAutoVolumeName[] = { NS_LITERAL_CSTRING("sdcard
|
||||
**************************************************************************/
|
||||
|
||||
static bool
|
||||
ReadSysFile(const char* aFilename, char* aBuf, size_t aBufSize)
|
||||
ReadSysFile(const char *aFilename, char *aBuf, size_t aBufSize)
|
||||
{
|
||||
int fd = open(aFilename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@ -117,7 +117,7 @@ ReadSysFile(const char* aFilename, char* aBuf, size_t aBufSize)
|
||||
}
|
||||
|
||||
static bool
|
||||
ReadSysFile(const char* aFilename, bool* aVal)
|
||||
ReadSysFile(const char *aFilename, bool *aVal)
|
||||
{
|
||||
char valBuf[20];
|
||||
if (!ReadSysFile(aFilename, valBuf, sizeof(valBuf))) {
|
||||
@ -133,7 +133,7 @@ ReadSysFile(const char* aFilename, bool* aVal)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
inline const char* SwitchStateStr(const SwitchEvent& aEvent)
|
||||
inline const char *SwitchStateStr(const SwitchEvent &aEvent)
|
||||
{
|
||||
return aEvent.status() == SWITCH_STATE_ON ? "plugged" : "unplugged";
|
||||
}
|
||||
@ -168,7 +168,7 @@ IsUsbCablePluggedIn()
|
||||
class AutoVolumeManagerStateObserver : public VolumeManager::StateObserver
|
||||
{
|
||||
public:
|
||||
virtual void Notify(const VolumeManager::StateChangedEvent& aEvent);
|
||||
virtual void Notify(const VolumeManager::StateChangedEvent &aEvent);
|
||||
};
|
||||
|
||||
// The AutoVolumeEventObserver allows the AutoMounter to know about card
|
||||
@ -176,7 +176,7 @@ public:
|
||||
class AutoVolumeEventObserver : public Volume::EventObserver
|
||||
{
|
||||
public:
|
||||
virtual void Notify(Volume * const & aEvent);
|
||||
virtual void Notify(Volume * const &aEvent);
|
||||
};
|
||||
|
||||
class AutoMounterResponseCallback : public VolumeResponseCallback
|
||||
@ -188,7 +188,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void ResponseReceived(const VolumeCommand* aCommand);
|
||||
virtual void ResponseReceived(const VolumeCommand *aCommand);
|
||||
|
||||
private:
|
||||
const static int kMaxErrorCount = 3; // Max number of errors before we give up
|
||||
@ -236,7 +236,7 @@ public:
|
||||
|
||||
void UpdateState();
|
||||
|
||||
const char* ModeStr(int32_t aMode)
|
||||
const char *ModeStr(int32_t aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case AUTOMOUNTER_DISABLE: return "Disable";
|
||||
@ -313,7 +313,7 @@ AutoVolumeEventObserver::Notify(Volume * const &)
|
||||
}
|
||||
|
||||
void
|
||||
AutoMounterResponseCallback::ResponseReceived(const VolumeCommand* aCommand)
|
||||
AutoMounterResponseCallback::ResponseReceived(const VolumeCommand *aCommand)
|
||||
{
|
||||
|
||||
if (WasSuccessful()) {
|
||||
@ -398,16 +398,8 @@ AutoMounter::UpdateState()
|
||||
RefPtr<Volume> vol = mAutoVolume[volIndex];
|
||||
Volume::STATE volState = vol->State();
|
||||
|
||||
if (vol->State() == nsIVolume::STATE_MOUNTED) {
|
||||
LOG("UpdateState: Volume %s is %s and %s @ %s gen %d locked %d",
|
||||
vol->NameStr(), vol->StateStr(),
|
||||
vol->MediaPresent() ? "inserted" : "missing",
|
||||
vol->MountPoint().get(), vol->MountGeneration(),
|
||||
(int)vol->IsMountLocked());
|
||||
} else {
|
||||
LOG("UpdateState: Volume %s is %s and %s", vol->NameStr(), vol->StateStr(),
|
||||
vol->MediaPresent() ? "inserted" : "missing");
|
||||
}
|
||||
LOG("UpdateState: Volume %s is %s and %s", vol->NameStr(), vol->StateStr(),
|
||||
vol->MediaPresent() ? "inserted" : "missing");
|
||||
if (!vol->MediaPresent()) {
|
||||
// No media - nothing we can do
|
||||
continue;
|
||||
@ -417,24 +409,17 @@ AutoMounter::UpdateState()
|
||||
// We're going to try to unmount and share the volumes
|
||||
switch (volState) {
|
||||
case nsIVolume::STATE_MOUNTED: {
|
||||
if (vol->IsMountLocked()) {
|
||||
// The volume is currently locked, so leave it in the mounted
|
||||
// state.
|
||||
DBG("UpdateState: Mounted volume %s is locked, leaving",
|
||||
vol->NameStr());
|
||||
break;
|
||||
}
|
||||
// Volume is mounted, we need to unmount before
|
||||
// we can share.
|
||||
DBG("UpdateState: Unmounting %s", vol->NameStr());
|
||||
vol->StartUnmount(mResponseCallback);
|
||||
return; // UpdateState will be called again when the Unmount command completes
|
||||
return;
|
||||
}
|
||||
case nsIVolume::STATE_IDLE: {
|
||||
// Volume is unmounted. We can go ahead and share.
|
||||
DBG("UpdateState: Sharing %s", vol->NameStr());
|
||||
vol->StartShare(mResponseCallback);
|
||||
return; // UpdateState will be called again when the Share command completes
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
// Not in a state that we can do anything about.
|
||||
@ -448,14 +433,14 @@ AutoMounter::UpdateState()
|
||||
// Volume is shared. We can go ahead and unshare.
|
||||
DBG("UpdateState: Unsharing %s", vol->NameStr());
|
||||
vol->StartUnshare(mResponseCallback);
|
||||
return; // UpdateState will be called again when the Unshare command completes
|
||||
return;
|
||||
}
|
||||
case nsIVolume::STATE_IDLE: {
|
||||
// Volume is unmounted, try to mount.
|
||||
|
||||
DBG("UpdateState: Mounting %s", vol->NameStr());
|
||||
vol->StartMount(mResponseCallback);
|
||||
return; // UpdateState will be called again when Mount command completes
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
// Not in a state that we can do anything about.
|
||||
@ -487,7 +472,7 @@ ShutdownAutoMounterIOThread()
|
||||
}
|
||||
|
||||
static void
|
||||
SetAutoMounterModeIOThread(const int32_t& aMode)
|
||||
SetAutoMounterModeIOThread(const int32_t &aMode)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(sAutoMounter);
|
||||
@ -530,7 +515,7 @@ public:
|
||||
UnregisterSwitchObserver(SWITCH_USB, this);
|
||||
}
|
||||
|
||||
virtual void Notify(const SwitchEvent& aEvent)
|
||||
virtual void Notify(const SwitchEvent &aEvent)
|
||||
{
|
||||
DBG("UsbCable switch device: %d state: %s\n",
|
||||
aEvent.device(), SwitchStateStr(aEvent));
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
|
||||
SettingsServiceCallback() {}
|
||||
|
||||
NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult) {
|
||||
NS_IMETHOD Handle(const nsAString &aName, const JS::Value &aResult) {
|
||||
if (JSVAL_IS_INT(aResult)) {
|
||||
int32_t mode = JSVAL_TO_INT(aResult);
|
||||
SetAutoMounterMode(mode);
|
||||
@ -43,7 +43,7 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleError(const nsAString& aName) {
|
||||
NS_IMETHOD HandleError(const nsAString &aName) {
|
||||
ERR("SettingsCallback::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
|
||||
return NS_OK;
|
||||
}
|
||||
@ -95,9 +95,9 @@ AutoMounterSetting::~AutoMounterSetting()
|
||||
NS_IMPL_ISUPPORTS1(AutoMounterSetting, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
AutoMounterSetting::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
AutoMounterSetting::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
|
||||
return NS_OK;
|
||||
@ -115,7 +115,7 @@ AutoMounterSetting::Observe(nsISupports* aSubject,
|
||||
ERR("Failed to get JSContextStack");
|
||||
return NS_OK;
|
||||
}
|
||||
JSContext* cx = stack->GetSafeJSContext();
|
||||
JSContext *cx = stack->GetSafeJSContext();
|
||||
if (!cx) {
|
||||
ERR("Failed to GetSafeJSContext");
|
||||
return NS_OK;
|
||||
@ -126,7 +126,7 @@ AutoMounterSetting::Observe(nsISupports* aSubject,
|
||||
!val.isObject()) {
|
||||
return NS_OK;
|
||||
}
|
||||
JSObject& obj(val.toObject());
|
||||
JSObject &obj(val.toObject());
|
||||
JS::Value key;
|
||||
if (!JS_GetProperty(cx, &obj, "key", &key) ||
|
||||
!key.isString()) {
|
||||
|
@ -39,7 +39,6 @@ XPIDLSRCS = \
|
||||
nsINetworkManager.idl \
|
||||
nsIRadioInterfaceLayer.idl \
|
||||
nsIVolume.idl \
|
||||
nsIVolumeMountLock.idl \
|
||||
nsIVolumeService.idl \
|
||||
nsIVolumeStat.idl \
|
||||
nsIWorkerHolder.idl \
|
||||
@ -64,7 +63,6 @@ CPPSRCS += \
|
||||
GonkGPSGeolocationProvider.cpp \
|
||||
AudioChannelManager.cpp \
|
||||
nsVolume.cpp \
|
||||
nsVolumeMountLock.cpp \
|
||||
nsVolumeService.cpp \
|
||||
nsVolumeStat.cpp \
|
||||
TimeZoneSettingObserver.cpp \
|
||||
@ -77,8 +75,8 @@ CPPSRCS += \
|
||||
# for our local copy of AudioSystem.h
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/media/libsydneyaudio/src
|
||||
EXPORTS = \
|
||||
GonkGPSGeolocationProvider.h \
|
||||
nsVolume.h \
|
||||
GonkGPSGeolocationProvider.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -16,48 +16,12 @@ namespace system {
|
||||
|
||||
Volume::EventObserverList Volume::mEventObserverList;
|
||||
|
||||
// We have a feature where volumes can be locked when mounted. This
|
||||
// is used to prevent a volume from being shared with the PC while
|
||||
// it is actively being used (say for storing an update image)
|
||||
//
|
||||
// We use WakeLocks (a poor choice of name, but it does what we want)
|
||||
// from the PowerManagerService to determine when we're locked.
|
||||
// In particular we'll create a wakelock called volume-NAME-GENERATION
|
||||
// (where NAME is the volume name, and GENERATION is its generation
|
||||
// number), and if this wakelock is locked, then we'll prevent a volume
|
||||
// from being shared.
|
||||
//
|
||||
// Implementation Details:
|
||||
//
|
||||
// Since the AutoMounter can only control when something gets mounted
|
||||
// and not when it gets unmounted (for example: a user pulls the SDCard)
|
||||
// and because Volume and nsVolume data structures are maintained on
|
||||
// separate threads, we have the potential for some race conditions.
|
||||
// We eliminate the race conditions by introducing the concept of a
|
||||
// generation number. Every time a volume transitions to the Mounted
|
||||
// state, it gets assigned a new generation number. Whenever the state
|
||||
// of a Volume changes, we send the updated state and current generation
|
||||
// number to the main thread where it gets updated in the nsVolume.
|
||||
//
|
||||
// Since WakeLocks can only be queried from the main-thread, the
|
||||
// nsVolumeService looks for WakeLock status changes, and forwards
|
||||
// the results to the IOThread.
|
||||
//
|
||||
// If the Volume (IOThread) recieves a volume update where the generation
|
||||
// number mismatches, then the update is simply ignored.
|
||||
//
|
||||
// When a Volume (IOThread) initially becomes mounted, we assume it to
|
||||
// be locked until we get our first update from nsVolume (MainThread).
|
||||
static int32_t sMountGeneration = 0;
|
||||
|
||||
// We don't get media inserted/removed events at startup. So we
|
||||
// assume it's present, and we'll be told that it's missing.
|
||||
Volume::Volume(const nsCSubstring& aName)
|
||||
Volume::Volume(const nsCSubstring &aName)
|
||||
: mMediaPresent(true),
|
||||
mState(nsIVolume::STATE_INIT),
|
||||
mName(aName),
|
||||
mMountGeneration(-1),
|
||||
mMountLocked(true) // Needs to agree with nsVolume::nsVolume
|
||||
mName(aName)
|
||||
{
|
||||
DBG("Volume %s: created", NameStr());
|
||||
}
|
||||
@ -65,9 +29,6 @@ Volume::Volume(const nsCSubstring& aName)
|
||||
void
|
||||
Volume::SetMediaPresent(bool aMediaPresent)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
// mMediaPresent is slightly redunant to the state, however
|
||||
// when media is removed (while Idle), we get the following:
|
||||
// 631 Volume sdcard /mnt/sdcard disk removed (179:0)
|
||||
@ -103,19 +64,13 @@ Volume::SetMediaPresent(bool aMediaPresent)
|
||||
void
|
||||
Volume::SetState(Volume::STATE aNewState)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
if (aNewState == mState) {
|
||||
return;
|
||||
}
|
||||
if (aNewState == nsIVolume::STATE_MOUNTED) {
|
||||
mMountGeneration = ++sMountGeneration;
|
||||
LOG("Volume %s: changing state from %s to %s @ '%s' (%d observers) "
|
||||
"mountGeneration = %d, locked = %d",
|
||||
LOG("Volume %s: changing state from %s to %s @ '%s' (%d observers)",
|
||||
NameStr(), StateStr(mState),
|
||||
StateStr(aNewState), mMountPoint.get(), mEventObserverList.Length(),
|
||||
mMountGeneration, (int)mMountLocked);
|
||||
StateStr(aNewState), mMountPoint.get(), mEventObserverList.Length());
|
||||
} else {
|
||||
LOG("Volume %s: changing state from %s to %s (%d observers)",
|
||||
NameStr(), StateStr(mState),
|
||||
@ -131,11 +86,8 @@ Volume::SetState(Volume::STATE aNewState)
|
||||
}
|
||||
|
||||
void
|
||||
Volume::SetMountPoint(const nsCSubstring& aMountPoint)
|
||||
Volume::SetMountPoint(const nsCSubstring &aMountPoint)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
if (mMountPoint.Equals(aMountPoint)) {
|
||||
return;
|
||||
}
|
||||
@ -144,55 +96,39 @@ Volume::SetMountPoint(const nsCSubstring& aMountPoint)
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartMount(VolumeResponseCallback* aCallback)
|
||||
Volume::StartMount(VolumeResponseCallback *aCallback)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
StartCommand(new VolumeActionCommand(this, "mount", "", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartUnmount(VolumeResponseCallback* aCallback)
|
||||
Volume::StartUnmount(VolumeResponseCallback *aCallback)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
StartCommand(new VolumeActionCommand(this, "unmount", "force", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartShare(VolumeResponseCallback* aCallback)
|
||||
Volume::StartShare(VolumeResponseCallback *aCallback)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
StartCommand(new VolumeActionCommand(this, "share", "ums", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartUnshare(VolumeResponseCallback* aCallback)
|
||||
Volume::StartUnshare(VolumeResponseCallback *aCallback)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
StartCommand(new VolumeActionCommand(this, "unshare", "ums", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartCommand(VolumeCommand* aCommand)
|
||||
Volume::StartCommand(VolumeCommand *aCommand)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
VolumeManager::PostCommand(aCommand);
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
Volume::RegisterObserver(Volume::EventObserver* aObserver)
|
||||
Volume::RegisterObserver(Volume::EventObserver *aObserver)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
mEventObserverList.AddObserver(aObserver);
|
||||
@ -206,40 +142,16 @@ Volume::RegisterObserver(Volume::EventObserver* aObserver)
|
||||
|
||||
//static
|
||||
void
|
||||
Volume::UnregisterObserver(Volume::EventObserver* aObserver)
|
||||
Volume::UnregisterObserver(Volume::EventObserver *aObserver)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
mEventObserverList.RemoveObserver(aObserver);
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
Volume::UpdateMountLock(const nsACString& aVolumeName,
|
||||
const int32_t& aMountGeneration,
|
||||
const bool& aMountLocked)
|
||||
Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer &aTokenizer)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
|
||||
if (!vol || (vol->mMountGeneration != aMountGeneration)) {
|
||||
return;
|
||||
}
|
||||
if (vol->mMountLocked != aMountLocked) {
|
||||
vol->mMountLocked = aMountLocked;
|
||||
DBG("Volume::UpdateMountLock for '%s' to %d\n", vol->NameStr(), (int)aMountLocked);
|
||||
mEventObserverList.Broadcast(vol);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
// The volume name will have already been parsed, and the tokenizer will point
|
||||
// to the token after the volume name
|
||||
switch (aResponseCode) {
|
||||
|
@ -27,63 +27,54 @@ namespace system {
|
||||
class Volume : public RefCounted<Volume>
|
||||
{
|
||||
public:
|
||||
Volume(const nsCSubstring& aVolumeName);
|
||||
Volume(const nsCSubstring &aVolumeName);
|
||||
|
||||
typedef long STATE; // States are now defined in nsIVolume.idl
|
||||
|
||||
static const char* StateStr(STATE aState) { return NS_VolumeStateStr(aState); }
|
||||
const char* StateStr() const { return StateStr(mState); }
|
||||
static const char *StateStr(STATE aState) { return NS_VolumeStateStr(aState); }
|
||||
const char *StateStr() const { return StateStr(mState); }
|
||||
STATE State() const { return mState; }
|
||||
|
||||
const nsCString& Name() const { return mName; }
|
||||
const char* NameStr() const { return mName.get(); }
|
||||
const nsCString &Name() const { return mName; }
|
||||
const char *NameStr() const { return mName.get(); }
|
||||
|
||||
// The mount point is the name of the directory where the volume is mounted.
|
||||
// (i.e. path that leads to the files stored on the volume).
|
||||
const nsCString& MountPoint() const { return mMountPoint; }
|
||||
const nsCString &MountPoint() const { return mMountPoint; }
|
||||
|
||||
int32_t MountGeneration() const { return mMountGeneration; }
|
||||
bool IsMountLocked() const { return mMountLocked; }
|
||||
bool MediaPresent() const { return mMediaPresent; }
|
||||
bool MediaPresent() const { return mMediaPresent; }
|
||||
|
||||
typedef mozilla::Observer<Volume *> EventObserver;
|
||||
typedef mozilla::ObserverList<Volume *> EventObserverList;
|
||||
|
||||
// NOTE: that observers must live in the IOThread.
|
||||
static void RegisterObserver(EventObserver* aObserver);
|
||||
static void UnregisterObserver(EventObserver* aObserver);
|
||||
static void RegisterObserver(EventObserver *aObserver);
|
||||
static void UnregisterObserver(EventObserver *aObserver);
|
||||
|
||||
private:
|
||||
friend class AutoMounter; // Calls StartXxx
|
||||
friend class nsVolume; // Calls UpdateMountLock
|
||||
friend class VolumeManager; // Calls HandleVoldResponse
|
||||
friend class VolumeListCallback; // Calls SetMountPoint, SetState
|
||||
|
||||
// The StartXxx functions will queue up a command to the VolumeManager.
|
||||
// You can queue up as many commands as you like, and aCallback will
|
||||
// be called as each one completes.
|
||||
void StartMount(VolumeResponseCallback* aCallback);
|
||||
void StartUnmount(VolumeResponseCallback* aCallback);
|
||||
void StartShare(VolumeResponseCallback* aCallback);
|
||||
void StartUnshare(VolumeResponseCallback* aCallback);
|
||||
void StartMount(VolumeResponseCallback *aCallback);
|
||||
void StartUnmount(VolumeResponseCallback *aCallback);
|
||||
void StartShare(VolumeResponseCallback *aCallback);
|
||||
void StartUnshare(VolumeResponseCallback *aCallback);
|
||||
|
||||
void SetState(STATE aNewState);
|
||||
void SetMediaPresent(bool aMediaPresent);
|
||||
void SetMountPoint(const nsCSubstring& aMountPoint);
|
||||
void StartCommand(VolumeCommand* aCommand);
|
||||
void SetMountPoint(const nsCSubstring &aMountPoint);
|
||||
void StartCommand(VolumeCommand *aCommand);
|
||||
|
||||
void HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer);
|
||||
|
||||
static void UpdateMountLock(const nsACString& aVolumeName,
|
||||
const int32_t& aMountGeneration,
|
||||
const bool& aMountLocked);
|
||||
void HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer &aTokenizer);
|
||||
|
||||
bool mMediaPresent;
|
||||
STATE mState;
|
||||
const nsCString mName;
|
||||
nsCString mMountPoint;
|
||||
int32_t mMountGeneration;
|
||||
bool mMountLocked;
|
||||
|
||||
static EventObserverList mEventObserverList;
|
||||
};
|
||||
|
@ -39,10 +39,10 @@ namespace system {
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
VolumeActionCommand::VolumeActionCommand(Volume* aVolume,
|
||||
const char* aAction,
|
||||
const char* aExtraArgs,
|
||||
VolumeResponseCallback* aCallback)
|
||||
VolumeActionCommand::VolumeActionCommand(Volume *aVolume,
|
||||
const char *aAction,
|
||||
const char *aExtraArgs,
|
||||
VolumeResponseCallback *aCallback)
|
||||
: VolumeCommand(aCallback),
|
||||
mVolume(aVolume)
|
||||
{
|
||||
@ -75,7 +75,7 @@ VolumeActionCommand::VolumeActionCommand(Volume* aVolume,
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
VolumeListCommand::VolumeListCommand(VolumeResponseCallback* aCallback)
|
||||
VolumeListCommand::VolumeListCommand(VolumeResponseCallback *aCallback)
|
||||
: VolumeCommand(NS_LITERAL_CSTRING("volume list"), aCallback)
|
||||
{
|
||||
}
|
||||
|
@ -59,14 +59,14 @@ public:
|
||||
const nsCString &ResponseStr() const { return mResponseStr; }
|
||||
|
||||
protected:
|
||||
virtual void ResponseReceived(const VolumeCommand* aCommand) = 0;
|
||||
virtual void ResponseReceived(const VolumeCommand *aCommand) = 0;
|
||||
|
||||
private:
|
||||
friend class VolumeCommand; // Calls HandleResponse and SetPending
|
||||
|
||||
void HandleResponse(const VolumeCommand* aCommand,
|
||||
void HandleResponse(const VolumeCommand *aCommand,
|
||||
int aResponseCode,
|
||||
nsACString& aResponseStr)
|
||||
nsACString &aResponseStr)
|
||||
{
|
||||
mResponseCode = aResponseCode;
|
||||
mResponseStr = aResponseStr;
|
||||
@ -102,14 +102,14 @@ private:
|
||||
class VolumeCommand : public RefCounted<VolumeCommand>
|
||||
{
|
||||
public:
|
||||
VolumeCommand(VolumeResponseCallback* aCallback)
|
||||
VolumeCommand(VolumeResponseCallback *aCallback)
|
||||
: mBytesConsumed(0),
|
||||
mCallback(aCallback)
|
||||
{
|
||||
SetCmd(NS_LITERAL_CSTRING(""));
|
||||
}
|
||||
|
||||
VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback)
|
||||
VolumeCommand(const nsACString &aCommand, VolumeResponseCallback *aCallback)
|
||||
: mBytesConsumed(0),
|
||||
mCallback(aCallback)
|
||||
{
|
||||
@ -118,7 +118,7 @@ public:
|
||||
|
||||
virtual ~VolumeCommand() {}
|
||||
|
||||
void SetCmd(const nsACString& aCommand)
|
||||
void SetCmd(const nsACString &aCommand)
|
||||
{
|
||||
mCmd = aCommand;
|
||||
// Add a null character. We want this to be included in the length since
|
||||
@ -126,8 +126,8 @@ public:
|
||||
mCmd.Append('\0');
|
||||
}
|
||||
|
||||
const char* CmdStr() const { return mCmd.get(); }
|
||||
const char* Data() const { return mCmd.Data() + mBytesConsumed; }
|
||||
const char *CmdStr() const { return mCmd.get(); }
|
||||
const char *Data() const { return mCmd.Data() + mBytesConsumed; }
|
||||
size_t BytesConsumed() const { return mBytesConsumed; }
|
||||
|
||||
size_t BytesRemaining() const
|
||||
@ -150,7 +150,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void HandleResponse(int aResponseCode, nsACString& aResponseStr)
|
||||
void HandleResponse(int aResponseCode, nsACString &aResponseStr)
|
||||
{
|
||||
if (mCallback) {
|
||||
mCallback->HandleResponse(this, aResponseCode, aResponseStr);
|
||||
@ -167,8 +167,8 @@ private:
|
||||
class VolumeActionCommand : public VolumeCommand
|
||||
{
|
||||
public:
|
||||
VolumeActionCommand(Volume* aVolume, const char* aAction,
|
||||
const char* aExtraArgs, VolumeResponseCallback* aCallback);
|
||||
VolumeActionCommand(Volume *aVolume, const char *aAction,
|
||||
const char *aExtraArgs, VolumeResponseCallback *aCallback);
|
||||
|
||||
private:
|
||||
RefPtr<Volume> mVolume;
|
||||
@ -177,7 +177,7 @@ private:
|
||||
class VolumeListCommand : public VolumeCommand
|
||||
{
|
||||
public:
|
||||
VolumeListCommand(VolumeResponseCallback* aCallback);
|
||||
VolumeListCommand(VolumeResponseCallback *aCallback);
|
||||
};
|
||||
|
||||
} // system
|
||||
|
@ -95,20 +95,20 @@ VolumeManager::SetState(STATE aNewState)
|
||||
|
||||
//static
|
||||
void
|
||||
VolumeManager::RegisterStateObserver(StateObserver* aObserver)
|
||||
VolumeManager::RegisterStateObserver(StateObserver *aObserver)
|
||||
{
|
||||
mStateObserverList.AddObserver(aObserver);
|
||||
}
|
||||
|
||||
//static
|
||||
void VolumeManager::UnregisterStateObserver(StateObserver* aObserver)
|
||||
void VolumeManager::UnregisterStateObserver(StateObserver *aObserver)
|
||||
{
|
||||
mStateObserverList.RemoveObserver(aObserver);
|
||||
}
|
||||
|
||||
//static
|
||||
TemporaryRef<Volume>
|
||||
VolumeManager::FindVolumeByName(const nsCSubstring& aName)
|
||||
VolumeManager::FindVolumeByName(const nsCSubstring &aName)
|
||||
{
|
||||
if (!sVolumeManager) {
|
||||
return NULL;
|
||||
@ -126,7 +126,7 @@ VolumeManager::FindVolumeByName(const nsCSubstring& aName)
|
||||
|
||||
//static
|
||||
TemporaryRef<Volume>
|
||||
VolumeManager::FindAddVolumeByName(const nsCSubstring& aName)
|
||||
VolumeManager::FindAddVolumeByName(const nsCSubstring &aName)
|
||||
{
|
||||
RefPtr<Volume> vol = FindVolumeByName(aName);
|
||||
if (vol) {
|
||||
@ -140,7 +140,7 @@ VolumeManager::FindAddVolumeByName(const nsCSubstring& aName)
|
||||
|
||||
class VolumeListCallback : public VolumeResponseCallback
|
||||
{
|
||||
virtual void ResponseReceived(const VolumeCommand* aCommand)
|
||||
virtual void ResponseReceived(const VolumeCommand *aCommand)
|
||||
{
|
||||
switch (ResponseCode()) {
|
||||
case ResponseCode::VolumeListResult: {
|
||||
@ -206,7 +206,7 @@ VolumeManager::OpenSocket()
|
||||
|
||||
//static
|
||||
void
|
||||
VolumeManager::PostCommand(VolumeCommand* aCommand)
|
||||
VolumeManager::PostCommand(VolumeCommand *aCommand)
|
||||
{
|
||||
if (!sVolumeManager) {
|
||||
ERR("VolumeManager not initialized. Dropping command '%s'", aCommand->Data());
|
||||
@ -241,7 +241,7 @@ VolumeManager::WriteCommandData()
|
||||
return;
|
||||
}
|
||||
|
||||
VolumeCommand* cmd = mCommands.front();
|
||||
VolumeCommand *cmd = mCommands.front();
|
||||
if (cmd->BytesRemaining() == 0) {
|
||||
// All bytes have been written. We're waiting for a response.
|
||||
return;
|
||||
@ -275,7 +275,7 @@ void
|
||||
VolumeManager::OnLineRead(int aFd, nsDependentCSubstring& aMessage)
|
||||
{
|
||||
MOZ_ASSERT(aFd == mSocket.get());
|
||||
char* endPtr;
|
||||
char *endPtr;
|
||||
int responseCode = strtol(aMessage.Data(), &endPtr, 10);
|
||||
if (*endPtr == ' ') {
|
||||
endPtr++;
|
||||
@ -292,7 +292,7 @@ VolumeManager::OnLineRead(int aFd, nsDependentCSubstring& aMessage)
|
||||
} else {
|
||||
// Everything else is considered to be part of the command response.
|
||||
if (mCommands.size() > 0) {
|
||||
VolumeCommand* cmd = mCommands.front();
|
||||
VolumeCommand *cmd = mCommands.front();
|
||||
cmd->HandleResponse(responseCode, responseLine);
|
||||
if (responseCode >= ResponseCode::CommandOkay) {
|
||||
// That's a terminating response. We can remove the command.
|
||||
@ -315,7 +315,7 @@ VolumeManager::OnFileCanWriteWithoutBlocking(int aFd)
|
||||
}
|
||||
|
||||
void
|
||||
VolumeManager::HandleBroadcast(int aResponseCode, nsCString& aResponseLine)
|
||||
VolumeManager::HandleBroadcast(int aResponseCode, nsCString &aResponseLine)
|
||||
{
|
||||
// Format of the line is something like:
|
||||
//
|
||||
|
@ -103,8 +103,8 @@ public:
|
||||
};
|
||||
|
||||
static STATE State();
|
||||
static const char* StateStr(STATE aState);
|
||||
static const char* StateStr() { return StateStr(State()); }
|
||||
static const char *StateStr(STATE aState);
|
||||
static const char *StateStr() { return StateStr(State()); }
|
||||
|
||||
class StateChangedEvent
|
||||
{
|
||||
@ -115,8 +115,8 @@ public:
|
||||
typedef mozilla::Observer<StateChangedEvent> StateObserver;
|
||||
typedef mozilla::ObserverList<StateChangedEvent> StateObserverList;
|
||||
|
||||
static void RegisterStateObserver(StateObserver* aObserver);
|
||||
static void UnregisterStateObserver(StateObserver* aObserver);
|
||||
static void RegisterStateObserver(StateObserver *aObserver);
|
||||
static void UnregisterStateObserver(StateObserver *aObserver);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@ -124,10 +124,10 @@ public:
|
||||
|
||||
static VolumeArray::size_type NumVolumes();
|
||||
static TemporaryRef<Volume> GetVolume(VolumeArray::index_type aIndex);
|
||||
static TemporaryRef<Volume> FindVolumeByName(const nsCSubstring& aName);
|
||||
static TemporaryRef<Volume> FindAddVolumeByName(const nsCSubstring& aName);
|
||||
static TemporaryRef<Volume> FindVolumeByName(const nsCSubstring &aName);
|
||||
static TemporaryRef<Volume> FindAddVolumeByName(const nsCSubstring &aName);
|
||||
|
||||
static void PostCommand(VolumeCommand* aCommand);
|
||||
static void PostCommand(VolumeCommand *aCommand);
|
||||
|
||||
protected:
|
||||
|
||||
@ -144,7 +144,7 @@ private:
|
||||
|
||||
void Restart();
|
||||
void WriteCommandData();
|
||||
void HandleBroadcast(int aResponseCode, nsCString& aResponseLine);
|
||||
void HandleBroadcast(int aResponseCode, nsCString &aResponseLine);
|
||||
|
||||
typedef std::queue<RefPtr<VolumeCommand> > CommandQueue;
|
||||
|
||||
|
@ -12,8 +12,7 @@
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
VolumeServiceIOThread::VolumeServiceIOThread(nsVolumeService* aVolumeService)
|
||||
: mVolumeService(aVolumeService)
|
||||
VolumeServiceIOThread::VolumeServiceIOThread()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
@ -30,17 +29,17 @@ VolumeServiceIOThread::~VolumeServiceIOThread()
|
||||
}
|
||||
|
||||
void
|
||||
VolumeServiceIOThread::Notify(Volume* const & aVolume)
|
||||
VolumeServiceIOThread::Notify(Volume * const &aVolume)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
|
||||
return;
|
||||
}
|
||||
mVolumeService->UpdateVolumeIOThread(aVolume);
|
||||
nsVolumeService::UpdateVolumeIOThread(aVolume);
|
||||
}
|
||||
|
||||
void
|
||||
VolumeServiceIOThread::Notify(const VolumeManager::StateChangedEvent& aEvent)
|
||||
VolumeServiceIOThread::Notify(const VolumeManager::StateChangedEvent &aEvent)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
UpdateAllVolumes();
|
||||
@ -58,17 +57,17 @@ VolumeServiceIOThread::UpdateAllVolumes()
|
||||
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
|
||||
mVolumeService->UpdateVolumeIOThread(vol);
|
||||
nsVolumeService::UpdateVolumeIOThread(vol);
|
||||
}
|
||||
}
|
||||
|
||||
static StaticRefPtr<VolumeServiceIOThread> sVolumeServiceIOThread;
|
||||
static RefPtr<VolumeServiceIOThread> sVolumeServiceIOThread;
|
||||
|
||||
void
|
||||
InitVolumeServiceIOThread(nsVolumeService* const & aVolumeService)
|
||||
InitVolumeServiceIOThread()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
sVolumeServiceIOThread = new VolumeServiceIOThread(aVolumeService);
|
||||
sVolumeServiceIOThread = new VolumeServiceIOThread();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -12,8 +12,6 @@
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
class nsVolumeService;
|
||||
|
||||
/***************************************************************************
|
||||
* The nsVolumeServiceIOThread is a companion class to the nsVolumeService
|
||||
* class, but whose methods are called from IOThread.
|
||||
@ -23,19 +21,18 @@ class VolumeServiceIOThread : public VolumeManager::StateObserver,
|
||||
public RefCounted<VolumeServiceIOThread>
|
||||
{
|
||||
public:
|
||||
VolumeServiceIOThread(nsVolumeService* aVolumeService);
|
||||
VolumeServiceIOThread();
|
||||
~VolumeServiceIOThread();
|
||||
|
||||
private:
|
||||
void UpdateAllVolumes();
|
||||
|
||||
virtual void Notify(const VolumeManager::StateChangedEvent& aEvent);
|
||||
virtual void Notify(Volume* const & aVolume);
|
||||
virtual void Notify(const VolumeManager::StateChangedEvent &aEvent);
|
||||
virtual void Notify(Volume * const &aVolume);
|
||||
|
||||
RefPtr<nsVolumeService> mVolumeService;
|
||||
};
|
||||
|
||||
void InitVolumeServiceIOThread(nsVolumeService* const & aVolumeService);
|
||||
void InitVolumeServiceIOThread();
|
||||
void ShutdownVolumeServiceIOThread();
|
||||
|
||||
} // system
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
|
||||
}
|
||||
|
||||
void LogVolume(nsIVolume* vol)
|
||||
void LogVolume(nsIVolume *vol)
|
||||
{
|
||||
nsString volName;
|
||||
nsString mountPoint;
|
||||
@ -92,9 +92,9 @@ static nsCOMPtr<VolumeTestObserver> sTestObserver;
|
||||
NS_IMPL_ISUPPORTS1(VolumeTestObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
VolumeTestObserver::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
VolumeTestObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
LOG("TestObserver: topic: %s", aTopic);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIVolumeStat.idl"
|
||||
|
||||
[scriptable, uuid(1134f267-7b81-42f2-b64a-6edb91286576)]
|
||||
[scriptable, uuid(3c9cae8d-9da2-4aa1-b8bf-4db8c8620808)]
|
||||
interface nsIVolume : nsISupports
|
||||
{
|
||||
// These MUST match the states from android's system/vold/Volume.h header
|
||||
@ -20,31 +20,12 @@ interface nsIVolume : nsISupports
|
||||
const long STATE_SHARED = 7;
|
||||
const long STATE_SHAREDMNT = 8;
|
||||
|
||||
// The name of the volume. Often there is only one volume, called sdcard.
|
||||
// But some phones support multiple volumes.
|
||||
readonly attribute DOMString name;
|
||||
|
||||
// The mount point is the path on the system where the volume is mounted
|
||||
// and is only valid when state == STATE_MOUNTED.
|
||||
readonly attribute DOMString mountPoint;
|
||||
|
||||
// Reflects the current state of the volume, using STATE_xxx constants
|
||||
// from above.
|
||||
readonly attribute long state;
|
||||
|
||||
// mountGeneration is a unique number which is used distinguish between
|
||||
// periods of time that a volume is in the mounted state. Each time a
|
||||
// volume transitions to the mounted state, the mountGeneration will
|
||||
// be different from the last time it transitioned to the mounted state.
|
||||
readonly attribute long mountGeneration;
|
||||
|
||||
// While a volume is mounted, it can be locked, preventing it from being
|
||||
// shared with the PC. To lock a volume, acquire an nsIDOMMozWakeLock
|
||||
// using the name of this attribute. Note that mountLockName changes
|
||||
// every time the mountGeneration changes, so you'll need to reacquire
|
||||
// the wakelock every time the volume becomes mounted.
|
||||
readonly attribute DOMString mountLockName;
|
||||
|
||||
nsIVolumeStat getStats();
|
||||
};
|
||||
|
||||
@ -56,7 +37,7 @@ namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
// Convert a state into a loggable/printable string.
|
||||
const char* NS_VolumeStateStr(int32_t aState);
|
||||
const char *NS_VolumeStateStr(int32_t aState);
|
||||
|
||||
} // system
|
||||
} // mozilla
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* 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 "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(44449f34-5ca1-4aff-bce6-22c79263de24)]
|
||||
interface nsIVolumeMountLock : nsISupports
|
||||
{
|
||||
void unlock();
|
||||
};
|
||||
|
@ -4,21 +4,16 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIVolume.idl"
|
||||
#include "nsIVolumeMountLock.idl"
|
||||
|
||||
[scriptable, uuid(597403c6-5ba4-4e7b-b3f4-ed3f05f775d8)]
|
||||
[scriptable, uuid(b31bd379-4bd2-4189-a85b-c0927a266a85)]
|
||||
interface nsIVolumeService : nsISupports
|
||||
{
|
||||
nsIVolume getVolumeByName(in DOMString volName);
|
||||
nsIVolume getVolumeByPath(in DOMString path);
|
||||
|
||||
void BroadcastVolume(in DOMString volName);
|
||||
|
||||
nsIVolumeMountLock createMountLock(in DOMString volName);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_VOLUMESERVICE_CID \
|
||||
{0x597403c6, 0x5ba4, 0x4e7b, {0xb3, 0xf4, 0xed, 0x3f, 0x05, 0xf7, 0x75, 0xd8}}
|
||||
{0xb31bd379, 0x4bd2, 0x4189, {0xa8, 0x5b, 0xc0, 0x92, 0x7a, 0x26, 0x6a, 0x85}}
|
||||
#define NS_VOLUMESERVICE_CONTRACTID "@mozilla.org/telephony/volume-service;1"
|
||||
%}
|
||||
|
@ -3,20 +3,11 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsVolume.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "nsIPowerManagerService.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsVolumeStat.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "Volume.h"
|
||||
|
||||
#define VOLUME_MANAGER_LOG_TAG "nsVolume"
|
||||
#include "VolumeManagerLog.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
@ -38,49 +29,28 @@ NS_VolumeStateStr(int32_t aState)
|
||||
return "???";
|
||||
}
|
||||
|
||||
// While nsVolumes can only be used on the main thread, in the
|
||||
// UpdateVolumeRunnable constructor (which is called from IOThread) we
|
||||
// allocate an nsVolume which is then passed to MainThread. Since we
|
||||
// have a situation where we allocate on one thread and free on another
|
||||
// we use a thread safe AddRef implementation.
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsVolume, nsIVolume)
|
||||
|
||||
nsVolume::nsVolume(const Volume* aVolume)
|
||||
nsVolume::nsVolume(const Volume *aVolume)
|
||||
: mName(NS_ConvertUTF8toUTF16(aVolume->Name())),
|
||||
mMountPoint(NS_ConvertUTF8toUTF16(aVolume->MountPoint())),
|
||||
mState(aVolume->State()),
|
||||
mMountGeneration(aVolume->MountGeneration()),
|
||||
mMountLocked(aVolume->IsMountLocked())
|
||||
mState(aVolume->State())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP nsVolume::GetName(nsAString &aName)
|
||||
{
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetMountGeneration(int32_t* aMountGeneration)
|
||||
{
|
||||
*aMountGeneration = mMountGeneration;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetMountLockName(nsAString& aMountLockName)
|
||||
{
|
||||
aMountLockName = NS_LITERAL_STRING("volume-") + Name();
|
||||
aMountLockName.AppendPrintf("-%d", mMountGeneration);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetMountPoint(nsAString& aMountPoint)
|
||||
NS_IMETHODIMP nsVolume::GetMountPoint(nsAString &aMountPoint)
|
||||
{
|
||||
aMountPoint = mMountPoint;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetState(int32_t* aState)
|
||||
NS_IMETHODIMP nsVolume::GetState(int32_t *aState)
|
||||
{
|
||||
*aState = mState;
|
||||
return NS_OK;
|
||||
@ -96,80 +66,5 @@ NS_IMETHODIMP nsVolume::GetStats(nsIVolumeStat **aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsVolume::LogState() const
|
||||
{
|
||||
if (mState == nsIVolume::STATE_MOUNTED) {
|
||||
LOG("nsVolume: %s state %s @ '%s' gen %d locked %d",
|
||||
NameStr(), StateStr(), MountPointStr(),
|
||||
MountGeneration(), (int)IsMountLocked());
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("nsVolume: %s state %s", NameStr(), StateStr());
|
||||
}
|
||||
|
||||
void nsVolume::Set(const nsVolume* aVolume)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mName = aVolume->mName;
|
||||
mMountPoint = aVolume->mMountPoint;
|
||||
mState = aVolume->mState;
|
||||
|
||||
if (mState != nsIVolume::STATE_MOUNTED) {
|
||||
// Since we're not in the mounted state, we need to
|
||||
// forgot whatever mount generation we may have had.
|
||||
mMountGeneration = -1;
|
||||
return;
|
||||
}
|
||||
if (mMountGeneration == aVolume->mMountGeneration) {
|
||||
// No change in mount generation, nothing else to do
|
||||
return;
|
||||
}
|
||||
|
||||
mMountGeneration = aVolume->mMountGeneration;
|
||||
|
||||
// Notify the Volume on IOThread whether the volume is locked or not.
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
if (!pmService) {
|
||||
return;
|
||||
}
|
||||
nsString mountLockName;
|
||||
GetMountLockName(mountLockName);
|
||||
nsString mountLockState;
|
||||
pmService->GetWakeLockState(mountLockName, mountLockState);
|
||||
UpdateMountLock(mountLockState);
|
||||
}
|
||||
|
||||
void
|
||||
nsVolume::UpdateMountLock(const nsAString& aMountLockState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// There are 3 states, unlocked, locked-background, and locked-foreground
|
||||
// I figured it was easier to use negtive logic and compare for unlocked.
|
||||
UpdateMountLock(!aMountLockState.EqualsLiteral("unlocked"));
|
||||
}
|
||||
|
||||
void
|
||||
nsVolume::UpdateMountLock(bool aMountLocked)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aMountLocked == mMountLocked) {
|
||||
return;
|
||||
}
|
||||
// The locked/unlocked state changed. Tell IOThread about it.
|
||||
mMountLocked = aMountLocked;
|
||||
LogState();
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(Volume::UpdateMountLock,
|
||||
NS_LossyConvertUTF16toASCII(Name()),
|
||||
MountGeneration(), aMountLocked));
|
||||
}
|
||||
|
||||
} // system
|
||||
} // mozilla
|
||||
|
@ -5,16 +5,13 @@
|
||||
#ifndef mozilla_system_nsvolume_h__
|
||||
#define mozilla_system_nsvolume_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
class Volume;
|
||||
class VolumeMountLock;
|
||||
|
||||
class nsVolume : public nsIVolume
|
||||
{
|
||||
@ -22,69 +19,51 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIVOLUME
|
||||
|
||||
// This constructor is used by the UpdateVolumeRunnable constructor
|
||||
nsVolume(const Volume* aVolume);
|
||||
nsVolume(const Volume *aVolume);
|
||||
|
||||
// This constructor is used by ContentChild::RecvFileSystemUpdate
|
||||
nsVolume(const nsAString& aName, const nsAString& aMountPoint,
|
||||
const int32_t& aState, const int32_t& aMountGeneration)
|
||||
: mName(aName),
|
||||
mMountPoint(aMountPoint),
|
||||
mState(aState),
|
||||
mMountGeneration(aMountGeneration),
|
||||
mMountLocked(false)
|
||||
nsVolume(const nsAString &aName, const nsAString &aMountPoint, const int32_t &aState)
|
||||
: mName(aName), mMountPoint(aMountPoint), mState(aState)
|
||||
{
|
||||
}
|
||||
|
||||
// This constructor is used by nsVolumeService::FindAddVolumeByName, and
|
||||
// will be followed shortly by a Set call.
|
||||
nsVolume(const nsAString& aName)
|
||||
nsVolume(const nsAString &aName)
|
||||
: mName(aName),
|
||||
mState(STATE_INIT),
|
||||
mMountGeneration(-1),
|
||||
mMountLocked(true) // Needs to agree with Volume::Volume
|
||||
mState(STATE_INIT)
|
||||
{
|
||||
}
|
||||
|
||||
bool Equals(const nsVolume* aVolume)
|
||||
bool Equals(const nsVolume *aVolume)
|
||||
{
|
||||
return mName.Equals(aVolume->mName)
|
||||
&& mMountPoint.Equals(aVolume->mMountPoint)
|
||||
&& (mState == aVolume->mState)
|
||||
&& (mMountGeneration == aVolume->mMountGeneration)
|
||||
&& (mMountLocked == aVolume->mMountLocked);
|
||||
&& (mState == aVolume->mState);
|
||||
}
|
||||
|
||||
void Set(const nsVolume* aVolume);
|
||||
void Set(const nsVolume *aVolume)
|
||||
{
|
||||
mName = aVolume->mName;
|
||||
mMountPoint = aVolume->mMountPoint;
|
||||
mState = aVolume->mState;
|
||||
}
|
||||
|
||||
void LogState() const;
|
||||
const nsString &Name() const { return mName; }
|
||||
const char *NameStr() const { return NS_LossyConvertUTF16toASCII(mName).get(); }
|
||||
|
||||
const nsString& Name() const { return mName; }
|
||||
const char* NameStr() const { return NS_LossyConvertUTF16toASCII(mName).get(); }
|
||||
|
||||
int32_t MountGeneration() const { return mMountGeneration; }
|
||||
bool IsMountLocked() const { return mMountLocked; }
|
||||
|
||||
const nsString& MountPoint() const { return mMountPoint; }
|
||||
const char* MountPointStr() const { return NS_LossyConvertUTF16toASCII(mMountPoint).get(); }
|
||||
const nsString &MountPoint() const { return mMountPoint; }
|
||||
const char *MountPointStr() const { return NS_LossyConvertUTF16toASCII(mMountPoint).get(); }
|
||||
|
||||
int32_t State() const { return mState; }
|
||||
const char* StateStr() const { return NS_VolumeStateStr(mState); }
|
||||
const char *StateStr() const { return NS_VolumeStateStr(mState); }
|
||||
|
||||
typedef nsTArray<nsRefPtr<nsVolume> > Array;
|
||||
|
||||
private:
|
||||
~nsVolume() {}
|
||||
|
||||
friend class nsVolumeService; // Calls the following XxxMountLock functions
|
||||
void UpdateMountLock(const nsAString& aMountLockState);
|
||||
void UpdateMountLock(bool aMountLocked);
|
||||
|
||||
protected:
|
||||
nsString mName;
|
||||
nsString mMountPoint;
|
||||
int32_t mState;
|
||||
int32_t mMountGeneration;
|
||||
bool mMountLocked;
|
||||
};
|
||||
|
||||
} // system
|
||||
|
@ -1,157 +0,0 @@
|
||||
/* 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 "nsVolumeMountLock.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPowerManagerService.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#define VOLUME_MANAGER_LOG_TAG "nsVolumeMountLock"
|
||||
#include "VolumeManagerLog.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::services;
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsVolumeMountLock, nsIVolumeMountLock,
|
||||
nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
// static
|
||||
already_AddRefed<nsVolumeMountLock>
|
||||
nsVolumeMountLock::Create(const nsAString& aVolumeName)
|
||||
{
|
||||
DBG("nsVolumeMountLock::Create called");
|
||||
|
||||
nsRefPtr<nsVolumeMountLock> mountLock = new nsVolumeMountLock(aVolumeName);
|
||||
nsresult rv = mountLock->Init();
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return mountLock.forget();
|
||||
}
|
||||
|
||||
nsVolumeMountLock::nsVolumeMountLock(const nsAString& aVolumeName)
|
||||
: mVolumeName(aVolumeName),
|
||||
mVolumeGeneration(-1),
|
||||
mUnlocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
nsVolumeMountLock::~nsVolumeMountLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
nsresult nsVolumeMountLock::Init()
|
||||
{
|
||||
LOG("nsVolumeMountLock created for '%s'",
|
||||
NS_LossyConvertUTF16toASCII(mVolumeName).get());
|
||||
|
||||
// Add ourselves as an Observer. It's important that we use a weak
|
||||
// reference here. If we used a strong reference, then that reference
|
||||
// would prevent this object from being destructed.
|
||||
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;
|
||||
}
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
|
||||
|
||||
vs->BroadcastVolume(mVolumeName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void unlock (); */
|
||||
NS_IMETHODIMP nsVolumeMountLock::Unlock()
|
||||
{
|
||||
LOG("nsVolumeMountLock released for '%s'",
|
||||
NS_LossyConvertUTF16toASCII(mVolumeName).get());
|
||||
|
||||
mUnlocked = true;
|
||||
mWakeLock = nullptr;
|
||||
|
||||
// While we don't really need to remove weak observers, we do so anyways
|
||||
// since it will reduce the number of times Observe gets called.
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeMountLock::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData)
|
||||
{
|
||||
if (strcmp(aTopic, NS_VOLUME_STATE_CHANGED) != 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (mUnlocked) {
|
||||
// We're not locked anymore, so we don't need to look at the notifications.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
|
||||
if (!vol) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsString volName;
|
||||
vol->GetName(volName);
|
||||
if (!volName.Equals(mVolumeName)) {
|
||||
return NS_OK;
|
||||
}
|
||||
int32_t state;
|
||||
nsresult rv = vol->GetState(&state);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (state != nsIVolume::STATE_MOUNTED) {
|
||||
mWakeLock = nullptr;
|
||||
mVolumeGeneration = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t mountGeneration;
|
||||
rv = vol->GetMountGeneration(&mountGeneration);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
DBG("nsVolumeMountLock::Observe mountGeneration = %d mVolumeGeneration = %d",
|
||||
mountGeneration, mVolumeGeneration);
|
||||
|
||||
if (mVolumeGeneration == mountGeneration) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The generation changed, which means that any wakelock we may have
|
||||
// been holding is now invalid. Grab a new wakelock for the new generation
|
||||
// number.
|
||||
|
||||
mWakeLock = nullptr;
|
||||
mVolumeGeneration = mountGeneration;
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pmService, NS_ERROR_FAILURE);
|
||||
|
||||
nsString mountLockName;
|
||||
vol->GetMountLockName(mountLockName);
|
||||
rv = pmService->NewWakeLock(mountLockName, nullptr, getter_AddRefs(mWakeLock));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LOG("nsVolumeMountLock acquired for '%s' gen %d",
|
||||
NS_LossyConvertUTF16toASCII(mVolumeName).get(), mVolumeGeneration);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace mozilla
|
@ -1,53 +0,0 @@
|
||||
/* 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_system_nsvolumemountlock_h__
|
||||
#define mozilla_system_nsvolumemountlock_h__
|
||||
|
||||
#include "nsIVolumeMountLock.h"
|
||||
|
||||
#include "nsIDOMWakeLock.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
/* The VolumeMountLock is designed so that it can be used in the Child or
|
||||
* Parent process. While the VolumeMountLock object exists, then the
|
||||
* VolumeManager/AutoMounter will prevent a mounted volume from being
|
||||
* shared with the PC.
|
||||
*/
|
||||
|
||||
class nsVolumeMountLock MOZ_FINAL : public nsIVolumeMountLock,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIVOLUMEMOUNTLOCK
|
||||
|
||||
static already_AddRefed<nsVolumeMountLock> Create(const nsAString& volumeName);
|
||||
|
||||
const nsString& VolumeName() const { return mVolumeName; }
|
||||
|
||||
private:
|
||||
nsVolumeMountLock(const nsAString& aVolumeName);
|
||||
~nsVolumeMountLock();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
nsString mVolumeName;
|
||||
int32_t mVolumeGeneration;
|
||||
nsCOMPtr<nsIDOMMozWakeLock> mWakeLock;
|
||||
bool mUnlocked;
|
||||
};
|
||||
|
||||
} // namespace system
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_system_nsvolumemountlock_h__
|
@ -11,10 +11,8 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDependentSubstring.h"
|
||||
#include "nsIDOMWakeLockListener.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPowerManagerService.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
@ -23,9 +21,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsVolumeMountLock.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#define VOLUME_MANAGER_LOG_TAG "nsVolumeService"
|
||||
@ -33,107 +29,31 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::services;
|
||||
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsVolumeService, nsIVolumeService, nsIDOMMozWakeLockListener)
|
||||
|
||||
StaticRefPtr<nsVolumeService> nsVolumeService::sSingleton;
|
||||
|
||||
// static
|
||||
already_AddRefed<nsVolumeService>
|
||||
nsVolumeService::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sSingleton) {
|
||||
sSingleton = new nsVolumeService();
|
||||
}
|
||||
NS_ADDREF(sSingleton.get());
|
||||
return sSingleton.get();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsVolumeService::Shutdown()
|
||||
{
|
||||
if (!sSingleton || (XRE_GetProcessType() != GeckoProcessType_Default)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
if (pmService) {
|
||||
pmService->RemoveWakeLockListener(sSingleton.get());
|
||||
}
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(ShutdownVolumeServiceIOThread));
|
||||
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
NS_IMPL_ISUPPORTS1(nsVolumeService, nsIVolumeService)
|
||||
|
||||
nsVolumeService::nsVolumeService()
|
||||
{
|
||||
sSingleton = this;
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
// We don't support the nsIVolumeService in the child processes,
|
||||
// but we get constructed due to the way we're registered with
|
||||
// nsLayoutModule.cpp. So we exit early to reduce our memory
|
||||
// impact, and so that we don't start unnecessary IOThread stuff.
|
||||
return;
|
||||
}
|
||||
|
||||
// Startup the IOThread side of things. The actual volume changes
|
||||
// are captured by the IOThread and forwarded to main thread.
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(InitVolumeServiceIOThread, this));
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
if (!pmService) {
|
||||
return;
|
||||
}
|
||||
pmService->AddWakeLockListener(this);
|
||||
NewRunnableFunction(InitVolumeServiceIOThread));
|
||||
}
|
||||
|
||||
nsVolumeService::~nsVolumeService()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(ShutdownVolumeServiceIOThread));
|
||||
}
|
||||
|
||||
// Callback for nsIDOMMozWakeLockListener
|
||||
NS_IMETHODIMP nsVolumeService::Callback(const nsAString& aTopic, const nsAString& aState)
|
||||
{
|
||||
CheckMountLock(aTopic, aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeService::BroadcastVolume(const nsAString& aVolName)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
nsRefPtr<nsVolume> 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());
|
||||
nsString stateStr(NS_ConvertUTF8toUTF16(vol->StateStr()));
|
||||
obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVolume **aResult)
|
||||
/* nsIVolume getVolumeByName (in DOMString volName); */
|
||||
NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString &aVolName, nsIVolume **aResult)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
nsRefPtr<nsVolume> vol = FindVolumeByName(aVolName);
|
||||
@ -147,7 +67,8 @@ NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVol
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeService::GetVolumeByPath(const nsAString& aPath, nsIVolume **aResult)
|
||||
/* nsIVolume getVolumeByPath (in DOMString path); */
|
||||
NS_IMETHODIMP nsVolumeService::GetVolumeByPath(const nsAString &aPath, nsIVolume **aResult)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
nsCString utf8Path = NS_ConvertUTF16toUTF8(aPath);
|
||||
@ -184,42 +105,12 @@ NS_IMETHODIMP nsVolumeService::GetVolumeByPath(const nsAString& aPath, nsIVolume
|
||||
// In order to support queries by DeviceStorage and the updater, we will fabricate
|
||||
// a volume from the pathname, so that the caller can determine the volume size
|
||||
nsRefPtr<nsVolume> vol = new nsVolume(NS_LITERAL_STRING("fake"),
|
||||
aPath, nsIVolume::STATE_MOUNTED,
|
||||
-1 /*generation*/);
|
||||
aPath, nsIVolume::STATE_MOUNTED);
|
||||
NS_ADDREF(*aResult = vol);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolumeService::CreateMountLock(const nsAString& aVolumeName, nsIVolumeMountLock **aResult)
|
||||
{
|
||||
nsRefPtr<nsVolumeMountLock> mountLock = nsVolumeMountLock::Create(aVolumeName);
|
||||
if (!mountLock) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
NS_ADDREF(*aResult = mountLock);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsVolumeService::CheckMountLock(const nsAString& aMountLockName,
|
||||
const nsAString& aMountLockState)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
|
||||
nsVolume::Array::index_type volIndex;
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
nsRefPtr<nsVolume> vol = mVolumeArray[volIndex];
|
||||
nsString mountLockName;
|
||||
vol->GetMountLockName(mountLockName);
|
||||
if (mountLockName.Equals(aMountLockName)) {
|
||||
vol->UpdateMountLock(aMountLockState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsVolume> nsVolumeService::FindVolumeByName(const nsAString& aName)
|
||||
already_AddRefed<nsVolume> nsVolumeService::FindVolumeByName(const nsAString &aName)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -235,8 +126,7 @@ already_AddRefed<nsVolume> nsVolumeService::FindVolumeByName(const nsAString& aN
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
already_AddRefed<nsVolume> nsVolumeService::FindAddVolumeByName(const nsAString& aName)
|
||||
already_AddRefed<nsVolume> nsVolumeService::FindAddVolumeByName(const nsAString &aName)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -252,7 +142,7 @@ already_AddRefed<nsVolume> nsVolumeService::FindAddVolumeByName(const nsAString&
|
||||
return vol.forget();
|
||||
}
|
||||
|
||||
void nsVolumeService::UpdateVolume(const nsVolume* aVolume)
|
||||
void nsVolumeService::UpdateVolume(const nsVolume *aVolume)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -267,6 +157,13 @@ void nsVolumeService::UpdateVolume(const nsVolume* aVolume)
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
if (aVolume->State() == nsIVolume::STATE_MOUNTED) {
|
||||
LOG("UpdateVolume: '%s' state %s @ '%s'",
|
||||
aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPointStr());
|
||||
} else {
|
||||
LOG("UpdateVolume: '%s' state %s",
|
||||
aVolume->NameStr(), aVolume->StateStr());
|
||||
}
|
||||
nsString stateStr(NS_ConvertUTF8toUTF16(vol->StateStr()));
|
||||
obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
}
|
||||
@ -278,9 +175,8 @@ void nsVolumeService::UpdateVolume(const nsVolume* aVolume)
|
||||
class UpdateVolumeRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UpdateVolumeRunnable(nsVolumeService* aVolumeService, const Volume* aVolume)
|
||||
: mVolumeService(aVolumeService),
|
||||
mVolume(new nsVolume(aVolume))
|
||||
UpdateVolumeRunnable(const Volume *aVolume)
|
||||
: mVolume(new nsVolume(aVolume))
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
}
|
||||
@ -288,29 +184,34 @@ public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DBG("UpdateVolumeRunnable::Run '%s' state %s gen %d locked %d",
|
||||
mVolume->NameStr(), mVolume->StateStr(), mVolume->MountGeneration(),
|
||||
(int)mVolume->IsMountLocked());
|
||||
DBG("UpdateVolumeRunnable::Run '%s' state %s",
|
||||
mVolume->NameStr(), mVolume->StateStr());
|
||||
|
||||
mVolumeService->UpdateVolume(mVolume);
|
||||
mVolumeService = NULL;
|
||||
nsCOMPtr<nsIVolumeService> ivs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
if (!ivs) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsVolumeService> vs(do_QueryInterface(ivs));
|
||||
if (!vs) {
|
||||
return NS_OK;
|
||||
}
|
||||
vs->UpdateVolume(mVolume);
|
||||
mVolume = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsVolumeService> mVolumeService;
|
||||
nsRefPtr<nsVolume> mVolume;
|
||||
nsRefPtr<nsVolume> mVolume;
|
||||
};
|
||||
|
||||
void nsVolumeService::UpdateVolumeIOThread(const Volume* aVolume)
|
||||
//static
|
||||
void nsVolumeService::UpdateVolumeIOThread(const Volume *aVolume)
|
||||
{
|
||||
DBG("UpdateVolumeIOThread: Volume '%s' state %s mount '%s' gen %d locked %d",
|
||||
aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPoint().get(),
|
||||
aVolume->MountGeneration(), (int)aVolume->IsMountLocked());
|
||||
DBG("UpdateVolumeIOThread: Volume '%s' state %s mount '%s'",
|
||||
aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPoint().get());
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
NS_DispatchToMainThread(new UpdateVolumeRunnable(this, aVolume));
|
||||
NS_DispatchToMainThread(new UpdateVolumeRunnable(aVolume));
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace mozilla
|
||||
} // system
|
||||
} // mozilla
|
||||
|
@ -5,10 +5,7 @@
|
||||
#ifndef mozilla_system_nsvolumeservice_h__
|
||||
#define mozilla_system_nsvolumeservice_h__
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMWakeLockListener.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
#include "nsVolume.h"
|
||||
@ -17,41 +14,29 @@
|
||||
namespace mozilla {
|
||||
namespace system {
|
||||
|
||||
class WakeLockCallback;
|
||||
|
||||
/***************************************************************************
|
||||
* The nsVolumeData class encapsulates the data that is updated/maintained
|
||||
* on the main thread in order to support the nsIVolume and nsIVolumeService
|
||||
* classes.
|
||||
*/
|
||||
|
||||
class nsVolumeService MOZ_FINAL : public nsIVolumeService,
|
||||
public nsIDOMMozWakeLockListener
|
||||
class nsVolumeService : public nsIVolumeService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIVOLUMESERVICE
|
||||
NS_DECL_NSIDOMMOZWAKELOCKLISTENER
|
||||
|
||||
nsVolumeService();
|
||||
|
||||
static already_AddRefed<nsVolumeService> GetSingleton();
|
||||
//static nsVolumeService* GetSingleton();
|
||||
static void Shutdown();
|
||||
|
||||
void CheckMountLock(const nsAString& aMountLockName,
|
||||
const nsAString& aMountLockState);
|
||||
already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName);
|
||||
already_AddRefed<nsVolume> FindAddVolumeByName(const nsAString& aName);
|
||||
void UpdateVolume(const nsVolume* aVolume);
|
||||
void UpdateVolumeIOThread(const Volume* aVolume);
|
||||
already_AddRefed<nsVolume> FindVolumeByName(const nsAString &aName);
|
||||
already_AddRefed<nsVolume> FindAddVolumeByName(const nsAString &aName);
|
||||
void UpdateVolume(const nsVolume *aVolume);
|
||||
static void UpdateVolumeIOThread(const Volume *aVolume);
|
||||
|
||||
private:
|
||||
~nsVolumeService();
|
||||
|
||||
nsVolume::Array mVolumeArray;
|
||||
|
||||
static StaticRefPtr<nsVolumeService> sSingleton;
|
||||
nsVolume::Array mVolumeArray;
|
||||
};
|
||||
|
||||
} // system
|
||||
|
@ -10,7 +10,7 @@ namespace system {
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsVolumeStat, nsIVolumeStat)
|
||||
|
||||
nsVolumeStat::nsVolumeStat(const nsAString& aPath)
|
||||
nsVolumeStat::nsVolumeStat(const nsAString &aPath)
|
||||
{
|
||||
nsCString utf8Path = NS_ConvertUTF16toUTF8(aPath);
|
||||
|
||||
@ -24,14 +24,14 @@ nsVolumeStat::~nsVolumeStat()
|
||||
}
|
||||
|
||||
/* readonly attribute long long totalBytes; */
|
||||
NS_IMETHODIMP nsVolumeStat::GetTotalBytes(int64_t* aTotalBytes)
|
||||
NS_IMETHODIMP nsVolumeStat::GetTotalBytes(int64_t *aTotalBytes)
|
||||
{
|
||||
*aTotalBytes = mStat.f_blocks * mStat.f_bsize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute long long freeBytes; */
|
||||
NS_IMETHODIMP nsVolumeStat::GetFreeBytes(int64_t* aFreeBytes)
|
||||
NS_IMETHODIMP nsVolumeStat::GetFreeBytes(int64_t *aFreeBytes)
|
||||
{
|
||||
*aFreeBytes = mStat.f_bfree * mStat.f_bsize;
|
||||
return NS_OK;
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIVOLUMESTAT
|
||||
|
||||
nsVolumeStat(const nsAString& aPath);
|
||||
nsVolumeStat(const nsAString &aPath);
|
||||
|
||||
private:
|
||||
~nsVolumeStat();
|
||||
|
@ -296,6 +296,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(BluetoothService,
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(AudioManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVolumeService)
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_FM
|
||||
@ -324,10 +325,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITimeService,
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIGeolocationProvider,
|
||||
GonkGPSGeolocationProvider::GetSingleton)
|
||||
// Since the nsVolumeService constructor calls into nsIPowerManagerService,
|
||||
// we need it to be constructed sometime after nsIPowerManagerService.
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsVolumeService,
|
||||
nsVolumeService::GetSingleton)
|
||||
#endif
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMediaManagerService,
|
||||
MediaManager::GetInstance)
|
||||
|
@ -87,11 +87,6 @@
|
||||
#include "AudioStream.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsVolumeService.h"
|
||||
using namespace mozilla::system;
|
||||
#endif
|
||||
|
||||
#include "nsError.h"
|
||||
|
||||
#include "nsCycleCollector.h"
|
||||
@ -354,10 +349,6 @@ nsLayoutStatics::Shutdown()
|
||||
WMFDecoder::UnloadDLLs();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsVolumeService::Shutdown();
|
||||
#endif
|
||||
|
||||
nsCORSListenerProxy::Shutdown();
|
||||
|
||||
nsIPresShell::ReleaseStatics();
|
||||
|
@ -74,18 +74,10 @@ const KEY_GRED = "GreD";
|
||||
#define USE_UPDROOT
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#define USE_UPDATE_ARCHIVE_DIR
|
||||
#endif
|
||||
|
||||
#ifdef USE_UPDROOT
|
||||
const KEY_UPDROOT = "UpdRootD";
|
||||
#endif
|
||||
|
||||
#ifdef USE_UPDATE_ARCHIVE_DIR
|
||||
const KEY_UPDATE_ARCHIVE_DIR = "UpdArchD"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define SKIP_STAGE_UPDATES_TEST
|
||||
#elifdef MOZ_WIDGET_GONK
|
||||
@ -107,8 +99,7 @@ const FILE_UPDATE_ARCHIVE = "update.apk";
|
||||
#else
|
||||
const FILE_UPDATE_ARCHIVE = "update.mar";
|
||||
#endif
|
||||
const FILE_UPDATE_LINK = "update.link";
|
||||
const FILE_UPDATE_LOG = "update.log";
|
||||
const FILE_UPDATE_LOG = "update.log"
|
||||
const FILE_UPDATES_DB = "updates.xml";
|
||||
const FILE_UPDATE_ACTIVE = "active-update.xml";
|
||||
const FILE_PERMS_TEST = "update.test";
|
||||
@ -164,7 +155,6 @@ const CERT_ATTR_CHECK_FAILED_NO_UPDATE = 100;
|
||||
const CERT_ATTR_CHECK_FAILED_HAS_UPDATE = 101;
|
||||
const BACKGROUNDCHECK_MULTIPLE_FAILURES = 110;
|
||||
const NETWORK_ERROR_OFFLINE = 111;
|
||||
const FILE_ERROR_TOO_BIG = 112;
|
||||
|
||||
const DOWNLOAD_CHUNK_SIZE = 300000; // bytes
|
||||
const DOWNLOAD_BACKGROUND_INTERVAL = 600; // seconds
|
||||
@ -184,12 +174,6 @@ const DEFAULT_SOCKET_MAX_ERRORS = 10;
|
||||
const DEFAULT_UPDATE_RETRY_TIMEOUT = 2000;
|
||||
|
||||
var gLocale = null;
|
||||
#ifdef MOZ_B2G
|
||||
var gVolumeMountLock = null;
|
||||
XPCOMUtils.defineLazyGetter(this, "gExtStorage", function aus_gExtStorage() {
|
||||
return Services.env.get("EXTERNAL_STORAGE");
|
||||
});
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
|
||||
"resource://gre/modules/UpdateChannel.jsm");
|
||||
@ -747,74 +731,6 @@ function writeStatusFile(dir, state) {
|
||||
writeStringToFile(statusFile, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the link file from the update.link file in the
|
||||
* specified directory.
|
||||
* @param dir
|
||||
* The dir to look for an update.link file in
|
||||
* @return The contents of the update.link file.
|
||||
*/
|
||||
function readLinkFile(dir) {
|
||||
var linkFile = dir.clone();
|
||||
linkFile.append(FILE_UPDATE_LINK);
|
||||
var link = readStringFromFile(linkFile) || STATE_NONE;
|
||||
LOG("readLinkFile - link: " + link + ", path: " + linkFile.path);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link file, which allows the actual patch to live in
|
||||
* a directory different from the update directory.
|
||||
* @param dir
|
||||
* The patch directory where the update.link file
|
||||
* should be written.
|
||||
* @param patchFile
|
||||
* The fully qualified filename of the patchfile.
|
||||
*/
|
||||
function writeLinkFile(dir, patchFile) {
|
||||
var linkFile = dir.clone();
|
||||
linkFile.append(FILE_UPDATE_LINK);
|
||||
writeStringToFile(linkFile, patchFile.path);
|
||||
#ifdef MOZ_B2G
|
||||
if (patchFile.path.indexOf(gExtStorage) == 0) {
|
||||
// The patchfile is being stored on external storage. Try to lock it
|
||||
// so that it doesn't get shared with the PC while we're downloading
|
||||
// to it.
|
||||
acquireSDCardMountLock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires a VolumeMountLock for the sdcard volume.
|
||||
*
|
||||
* This prevents the SDCard from being shared with the PC while
|
||||
* we're downloading the update.
|
||||
*/
|
||||
function acquireSDCardMountLock() {
|
||||
#ifdef MOZ_B2G
|
||||
let volsvc = Cc["@mozilla.org/telephony/volume-service;1"].
|
||||
getService(Ci.nsIVolumeService);
|
||||
if (volsvc) {
|
||||
gSDCardMountLock = volsvc.createMountLock("sdcard");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases any SDCard mount lock that we might have.
|
||||
*
|
||||
* This once again allows the SDCard to be shared with the PC.
|
||||
*/
|
||||
function releaseSDCardMountLock() {
|
||||
#ifdef MOZ_B2G
|
||||
if (gSDCardMountLock) {
|
||||
gSDCardMountLock.unlock();
|
||||
gSDCardMountLock = null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the service should be used to attempt an update
|
||||
* or not. For now this is only when PREF_APP_UPDATE_SERVICE_ENABLED
|
||||
@ -983,7 +899,6 @@ function cleanUpUpdatesDir(aBackgroundUpdate) {
|
||||
LOG("cleanUpUpdatesDir - failed to remove file " + f.path);
|
||||
}
|
||||
}
|
||||
releaseSDCardMountLock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2883,8 +2798,6 @@ UpdateManager.prototype = {
|
||||
var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Ci.nsIUpdatePrompt);
|
||||
prompter.showUpdateDownloaded(update, true);
|
||||
} else {
|
||||
releaseSDCardMountLock();
|
||||
}
|
||||
},
|
||||
|
||||
@ -3233,7 +3146,6 @@ Downloader.prototype = {
|
||||
if (this._request && this._request instanceof Ci.nsIRequest) {
|
||||
this._request.cancel(cancelError);
|
||||
}
|
||||
releaseSDCardMountLock();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -3404,28 +3316,6 @@ Downloader.prototype = {
|
||||
return this._request != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the nsIFile to use for downloading the active update's selected patch
|
||||
*/
|
||||
_getUpdateArchiveFile: function Downloader__getUpdateArchiveFile() {
|
||||
var updateArchive;
|
||||
#ifdef USE_UPDATE_ARCHIVE_DIR
|
||||
try {
|
||||
updateArchive = FileUtils.getDir(KEY_UPDATE_ARCHIVE_DIR, [], true);
|
||||
} catch (e) {
|
||||
if (e == Cr.NS_ERROR_FILE_TOO_BIG) {
|
||||
this._update.errorCode = FILE_ERROR_TOO_BIG;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#else
|
||||
updateArchive = getUpdatesDir().clone();
|
||||
#endif
|
||||
|
||||
updateArchive.append(FILE_UPDATE_ARCHIVE);
|
||||
return updateArchive;
|
||||
},
|
||||
|
||||
/**
|
||||
* Download and stage the given update.
|
||||
* @param update
|
||||
@ -3449,16 +3339,8 @@ Downloader.prototype = {
|
||||
}
|
||||
this.isCompleteUpdate = this._patch.type == "complete";
|
||||
|
||||
var patchFile = this._getUpdateArchiveFile();
|
||||
if (!patchFile) {
|
||||
return STATE_NONE;
|
||||
}
|
||||
|
||||
if (patchFile.path.indexOf(updateDir.path) != 0) {
|
||||
// The patchFile is in a directory which is different from the
|
||||
// updateDir, create a link file.
|
||||
writeLinkFile(updateDir, patchFile);
|
||||
}
|
||||
var patchFile = updateDir.clone();
|
||||
patchFile.append(FILE_UPDATE_ARCHIVE);
|
||||
|
||||
var uri = Services.io.newURI(this._patch.URL, null, null);
|
||||
|
||||
|
@ -2085,49 +2085,6 @@ ReadMARChannelIDs(const NS_tchar *path, MARChannelStringTable *results)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
GetUpdateFileName(NS_tchar *fileName, int maxChars)
|
||||
{
|
||||
#if defined(MOZ_WIDGET_GONK) // If an update.link file exists, then it will contain the name
|
||||
// of the update file (terminated by a newline).
|
||||
|
||||
NS_tchar linkFileName[MAXPATHLEN];
|
||||
NS_tsnprintf(linkFileName, sizeof(linkFileName)/sizeof(linkFileName[0]),
|
||||
NS_T("%s/update.link"), gSourcePath);
|
||||
AutoFile linkFile = NS_tfopen(linkFileName, NS_T("rb"));
|
||||
if (linkFile == NULL) {
|
||||
NS_tsnprintf(fileName, maxChars,
|
||||
NS_T("%s/update.mar"), gSourcePath);
|
||||
return OK;
|
||||
}
|
||||
|
||||
char dataFileName[MAXPATHLEN];
|
||||
size_t bytesRead;
|
||||
|
||||
if ((bytesRead = fread(dataFileName, 1, sizeof(dataFileName)-1, linkFile)) <= 0) {
|
||||
*fileName = NS_T('\0');
|
||||
return READ_ERROR;
|
||||
}
|
||||
if (dataFileName[bytesRead-1] == '\n') {
|
||||
// Strip trailing newline (for \n and \r\n)
|
||||
bytesRead--;
|
||||
}
|
||||
if (dataFileName[bytesRead-1] == '\r') {
|
||||
// Strip trailing CR (for \r, \r\n)
|
||||
bytesRead--;
|
||||
}
|
||||
dataFileName[bytesRead] = '\0';
|
||||
|
||||
strncpy(fileName, dataFileName, maxChars-1);
|
||||
fileName[maxChars-1] = '\0';
|
||||
#else
|
||||
// We currently only support update.link files under GONK
|
||||
NS_tsnprintf(fileName, maxChars,
|
||||
NS_T("%s/update.mar"), gSourcePath);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateThreadFunc(void *param)
|
||||
{
|
||||
@ -2137,10 +2094,10 @@ UpdateThreadFunc(void *param)
|
||||
rv = ProcessReplaceRequest();
|
||||
} else {
|
||||
NS_tchar dataFile[MAXPATHLEN];
|
||||
rv = GetUpdateFileName(dataFile, sizeof(dataFile)/sizeof(dataFile[0]));
|
||||
if (rv == OK) {
|
||||
rv = gArchiveReader.Open(dataFile);
|
||||
}
|
||||
NS_tsnprintf(dataFile, sizeof(dataFile)/sizeof(dataFile[0]),
|
||||
NS_T("%s/update.mar"), gSourcePath);
|
||||
|
||||
rv = gArchiveReader.Open(dataFile);
|
||||
|
||||
#ifdef MOZ_VERIFY_MAR_SIGNATURE
|
||||
if (rv == OK) {
|
||||
|
@ -987,17 +987,8 @@ nsUpdateProcessor::ProcessUpdate(nsIUpdate* aUpdate)
|
||||
if (dirProvider) { // Normal code path
|
||||
// Check for and process any available updates
|
||||
bool persistent;
|
||||
nsresult rv = NS_ERROR_FAILURE; // Take the NS_FAILED path when non-GONK
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Check in the sdcard for updates first, since that's our preferred
|
||||
// download location.
|
||||
rv = dirProvider->GetFile(XRE_UPDATE_ARCHIVE_DIR, &persistent,
|
||||
getter_AddRefs(updRoot));
|
||||
#endif
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = dirProvider->GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
|
||||
getter_AddRefs(updRoot));
|
||||
}
|
||||
nsresult rv = dirProvider->GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
|
||||
getter_AddRefs(updRoot));
|
||||
// XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
|
||||
if (NS_FAILED(rv))
|
||||
updRoot = dirProvider->GetAppDir();
|
||||
|
@ -123,14 +123,6 @@
|
||||
*/
|
||||
#define XRE_UPDATE_ROOT_DIR "UpdRootD"
|
||||
|
||||
/**
|
||||
* A directory service key which provides an alternate location
|
||||
* to UpdRootD to to store large files. This key is currently
|
||||
* only implemented in the Gonk directory service provider.
|
||||
*/
|
||||
|
||||
#define XRE_UPDATE_ARCHIVE_DIR "UpdArchD"
|
||||
|
||||
/**
|
||||
* A directory service key which provides the directory where an OS update is
|
||||
* applied.
|
||||
|
Loading…
Reference in New Issue
Block a user