home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 112
/
FreelogNo112-NovembreDecembre2012.iso
/
Multimedia
/
Songbird
/
Songbird_2.0.0-2311_windows-i686-msvc8.exe
/
components
/
sbCDRipServicePaneService.js
< prev
next >
Wrap
Text File
|
2012-06-08
|
22KB
|
650 lines
/*
*=BEGIN SONGBIRD GPL
*
* This file is part of the Songbird web player.
*
* Copyright(c) 2005-2010 POTI, Inc.
* http://www.songbirdnest.com
*
* This file may be licensed under the terms of of the
* GNU General Public License Version 2 (the ``GPL'').
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the GPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the GPL along with this
* program. If not, go to http://www.gnu.org/licenses/gpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*=END SONGBIRD GPL
*/
if (typeof(Cc) == "undefined")
var Cc = Components.classes;
if (typeof(Ci) == "undefined")
var Ci = Components.interfaces;
if (typeof(Cr) == "undefined")
var Cr = Components.results;
if (typeof(Cu) == "undefined")
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://app/jsmodules/ArrayConverter.jsm");
Cu.import("resource://app/jsmodules/DOMUtils.jsm");
Cu.import("resource://app/jsmodules/PlatformUtils.jsm");
Cu.import("resource://app/jsmodules/sbProperties.jsm");
const CDRIPNS = 'http://songbirdnest.com/rdf/servicepane/cdrip#';
const SPNS = 'http://songbirdnest.com/rdf/servicepane#';
// For some device events we need to check if they are from the CD Device
// marshall and not others.
const CDDEVICEMARSHALLNAME = "sbCDDeviceMarshall";
var sbCDRipServicePaneServiceConfig = {
className: "Songbird CD Rip Device Support Module",
cid: Components.ID("{9925b565-5c19-4feb-87a8-413d86570cd9}"),
contractID: "@songbirdnest.com/servicepane/cdDevice;1",
ifList: [ Ci.sbIServicePaneModule,
Ci.nsIObserver ],
categoryList:
[
{
category: "service-pane",
entry: "cdrip-device"
}
],
devCatName: "CD Rip Device",
appQuitTopic: "quit-application",
devMgrURL: "chrome://songbird/content/mediapages/cdripMediaView.xul"
};
if ("sbIWindowsAutoPlayActionHandler" in Ci) {
sbCDRipServicePaneServiceConfig.ifList.push(Ci.sbIWindowsAutoPlayActionHandler);
}
function sbCDRipServicePaneService() {
}
sbCDRipServicePaneService.prototype.constructor = sbCDRipServicePaneService;
sbCDRipServicePaneService.prototype = {
classDescription: sbCDRipServicePaneServiceConfig.className,
classID: sbCDRipServicePaneServiceConfig.cid,
contractID: sbCDRipServicePaneServiceConfig.contractID,
_cfg: sbCDRipServicePaneServiceConfig,
_xpcom_categories: sbCDRipServicePaneServiceConfig.categoryList,
// Services to use.
_deviceManagerSvc: null,
_deviceServicePaneSvc: null,
_observerSvc: null,
_servicePaneSvc: null,
_deviceInfoList: [],
_deviceScanInProgress: false,
// ************************************
// sbIServicePaneService implementation
// ************************************
servicePaneInit: function sbCDRipServicePaneService_servicePaneInit(aServicePaneService) {
this._servicePaneSvc = aServicePaneService;
this._initialize();
},
fillContextMenu: function sbCDRipServicePaneService_fillContextMenu(aNode,
aContextMenu,
aParentWindow) {
// Get the node device ID. Do nothing if not a device node.
var deviceID = aNode.getAttributeNS(CDRIPNS, "DeviceId");
if (!deviceID)
return;
// Get the device node type.
var deviceNodeType = aNode.getAttributeNS(CDRIPNS, "deviceNodeType");
// Import device context menu items into the context menu.
if (deviceNodeType == "cd-device") {
DOMUtils.importChildElements(aContextMenu,
this._deviceContextMenuDoc,
"cddevice_context_menu_items",
{ "device-id": deviceID,
"service_pane_node_id": aNode.id });
}
},
fillNewItemMenu: function sbCDRipServicePaneService_fillNewItemMenu(aNode,
aContextMenu,
aParentWindow) {
},
onSelectionChanged: function sbCDRipServicePaneService_onSelectionChanged(aNode,
aContainer,
aParentWindow) {
},
canDrop: function sbCDRipServicePaneService_canDrop(aNode,
aDragSession,
aOrientation,
aWindow) {
// Currently no drag and drop allowed
return false;
},
onDrop: function sbCDRipServicePaneService_onDrop(aNode,
aDragSession,
aOrientation,
aWindow) {
// Currently no drag and drop allowed
},
onDragGesture: function sbCDRipServicePaneService_onDragGesture(aNode,
aDataTransfer) {
// Currently no drag and drop allowed
},
onBeforeRename: function sbCDRipServicePaneService_onBeforeRename(aNode) {
// Rename is not allowed for CD Devices
},
onRename: function sbCDRipServicePaneService_onRename(aNode,
aNewName) {
// Rename is not allowed for CD Devices
},
shutdown: function sbCDRipServicePaneService_shutdown() {
// Do nothing, since we shut down on quit-application
},
// ************************************
// nsIObserver implementation
// ************************************
observe: function sbCDRipServicePaneService_observe(aSubject,
aTopic,
aData) {
switch (aTopic) {
case this._cfg.appQuitTopic :
this._shutdown();
break;
}
},
// ************************************
// nsISupports implementation
// ************************************
QueryInterface: XPCOMUtils.generateQI(sbCDRipServicePaneServiceConfig.ifList),
// ************************************
// Internal methods
// ************************************
/**
* \brief Initialize the CD Device nodes.
*/
_initialize: function sbCDRipServicePaneService_initialize() {
this._observerSvc = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
this._observerSvc.addObserver(this, this._cfg.appQuitTopic, false);
this._deviceServicePaneSvc = Cc["@songbirdnest.com/servicepane/device;1"]
.getService(Ci.sbIDeviceServicePaneService);
this._deviceManagerSvc = Cc["@songbirdnest.com/Songbird/DeviceManager;2"]
.getService(Ci.sbIDeviceManager2);
// Add a listener for CDDevice Events
var deviceEventListener = {
cdDeviceServicePaneSvc: this,
onDeviceEvent: function deviceEventListener_onDeviceEvent(aDeviceEvent) {
this.cdDeviceServicePaneSvc._processDeviceManagerEvent(aDeviceEvent);
}
};
this._deviceEventListener = deviceEventListener;
this._deviceManagerSvc.addEventListener(deviceEventListener);
// load the cd-device context menu document
this._deviceContextMenuDoc =
DOMUtils.loadDocument
("chrome://songbird/content/xul/device/deviceContextMenu.xul");
if (PlatformUtils.platformString == "Windows_NT") {
// Register autoplay handler
var autoPlayActionHandler = {
cdDeviceServicePaneSvc: this,
handleAction: function autoPlayActionHandler_handleAction(aAction, aActionArg) {
return this.cdDeviceServicePaneSvc._processAutoPlayAction(aAction);
},
QueryInterface: XPCOMUtils.generateQI([Ci.sbIWindowsAutoPlayActionHandler])
}
this._autoPlayActionHandler = autoPlayActionHandler;
var windowsAutoPlayService =
Cc["@songbirdnest.com/Songbird/WindowsAutoPlayService;1"]
.getService(Ci.sbIWindowsAutoPlayService);
windowsAutoPlayService.addActionHandler
(autoPlayActionHandler,
Ci.sbIWindowsAutoPlayService.ACTION_CD_RIP);
}
},
/**
* \brief Shutdown and remove the CD Device nodes.
*/
_shutdown: function sbCDRipServicePaneService_shutdown() {
this._observerSvc.removeObserver(this, this._cfg.appQuitTopic);
this._deviceManagerSvc.removeEventListener(this._deviceEventListener);
this._deviceEventListener = null;
if (PlatformUtils.platformString == "Windows_NT") {
// Unregister autoplay handler
var windowsAutoPlayService =
Cc["@songbirdnest.com/Songbird/WindowsAutoPlayService;1"]
.getService(Ci.sbIWindowsAutoPlayService);
windowsAutoPlayService.removeActionHandler
(this._autoPlayActionHandler,
Ci.sbIWindowsAutoPlayService.ACTION_CD_RIP);
this._autoPlayActionHandler = null;
}
// Remove all references to nodes
this._deviceInfoList = [];
this._deviceManagerSvc = null;
this._deviceServicePaneSvc = null;
this._servicePaneSvc = null;
this._observerSvc = null;
},
/**
* \brief Process events from the Device Manager.
* \param aDeviceEvent - Event that occured for a device.
*/
_processDeviceManagerEvent:
function sbCDRipServicePaneService_processDeviceManagerEvent(aDeviceEvent) {
switch(aDeviceEvent.type) {
case Ci.sbIDeviceEvent.EVENT_DEVICE_SCAN_START:
var marshall = aDeviceEvent.origin.QueryInterface(Ci.sbIDeviceMarshall);
if (marshall.name == CDDEVICEMARSHALLNAME)
this._deviceScanInProgress = true;
break;
case Ci.sbIDeviceEvent.EVENT_DEVICE_SCAN_END:
var marshall = aDeviceEvent.origin.QueryInterface(Ci.sbIDeviceMarshall);
if (marshall.name == CDDEVICEMARSHALLNAME)
this._deviceScanInProgress = false;
break;
case Ci.sbIDeviceEvent.EVENT_DEVICE_ADDED:
var result = this._addDeviceFromEvent(aDeviceEvent);
// if we successfully added the device, switch the media tab
// to the CD rip view as long as this is not during the initial scan
// of CD Devices.
if (result)
this._loadCDViewFromEvent(aDeviceEvent);
break;
case Ci.sbIDeviceEvent.EVENT_DEVICE_REMOVED:
this._removeDeviceFromEvent(aDeviceEvent);
break;
case Ci.sbICDDeviceEvent.EVENT_CDLOOKUP_INITIATED:
this._updateState(aDeviceEvent, true);
break;
case Ci.sbICDDeviceEvent.EVENT_CDLOOKUP_COMPLETED:
this._updateState(aDeviceEvent, false);
break;
case Ci.sbICDDeviceEvent.EVENT_CDLOOKUP_METADATA_COMPLETE:
this._updateState(aDeviceEvent, false);
break;
case Ci.sbIDeviceEvent.EVENT_DEVICE_STATE_CHANGED:
this._updateState(aDeviceEvent, false);
break;
default:
break;
}
},
/**
* \brief Handles autoplay actions initiated by the user.
* \param aAction - Action to be handled.
*/
_processAutoPlayAction:
function sbCDRipServicePaneService_processAutoPlayAction(aAction) {
switch (aAction) {
case Ci.sbIWindowsAutoPlayService.ACTION_CD_RIP:
// No way to tell which CD the user meant to rip, let's take one randomly
// (hopefully the last one enumerated is also the last one added)
var deviceNode = null;
for each (let deviceInfo in this._deviceInfoList) {
deviceNode = deviceInfo.svcPaneNode;
}
if (deviceNode) {
Cc['@mozilla.org/appshell/window-mediator;1']
.getService(Ci.nsIWindowMediator)
.getMostRecentWindow('Songbird:Main').gBrowser
.loadURI(deviceNode.url, null, null, null, "_media");
}
else {
// CD is probably not recognized yet, don't do anything - the view
// will switch to it anyway once it is.
}
return true;
default:
return false;
}
},
/**
* \brief Load the CD Rip media view as response to a device event
* \param aDeviceEvent - Device event being acted upon.
*/
_loadCDViewFromEvent:
function sbCDRipServicePaneService_loadCDViewFromEvent(aDeviceEvent) {
// We only want to do this if it is not during a device scan (usually at
// startup).
if (this._deviceScanInProgress)
return;
var device = aDeviceEvent.data.QueryInterface(Ci.sbIDevice);
var url = this._cfg.devMgrURL + "?device-id=" + device.id;
Cc['@mozilla.org/appshell/window-mediator;1']
.getService(Ci.nsIWindowMediator)
.getMostRecentWindow('Songbird:Main').gBrowser
.loadURI(url, null, null, null, "_media");
},
/**
* \brief Updates the state of the service pane node.
* \param aDeviceEvent - Device event of device.
*/
_updateState: function sbCDRipServicePaneService__updateState(aDeviceEvent,
aForceBusy) {
// Get the device and its node.
var device = aDeviceEvent.origin.QueryInterface(Ci.sbIDevice);
var deviceId = device.id;
var deviceType = device.parameters.getProperty("DeviceType");
// We only care about CD devices
if (deviceType != "CD")
return;
if (device.state == Ci.sbIDevice.STATE_TRANSCODE) {
this._toggleReadOnly(true, device);
}
else if (device.state == Ci.sbIDevice.STATE_IDLE) {
this._toggleReadOnly(false, device);
}
if (typeof(this._deviceInfoList[deviceId]) != 'undefined') {
var devNode = this._deviceInfoList[deviceId].svcPaneNode;
// The friendly name might have changed, keep it in sync.
if (devNode.name != device.properties.friendlyName) {
devNode.name = device.properties.friendlyName;
}
// Get the device properties and clear the busy property.
devProperties = devNode.className.split(" ");
devProperties = devProperties.filter(function(aProperty) {
return aProperty != "busy";
});
// Set the busy property if the device is busy.
if ((device.state != Ci.sbIDevice.STATE_CANCEL) &&
(aForceBusy || device.state != Ci.sbIDevice.STATE_IDLE)) {
// Clear success state from previous rip
devProperties = devProperties.filter(function(aProperty) {
return aProperty != "successful" &&
aProperty != "unsuccessful";
});
devProperties.push("busy");
} else {
if (devNode.hasAttributeNS(CDRIPNS, "LastState")) {
var lastState = devNode.getAttributeNS(CDRIPNS, "LastState");
if (lastState == Ci.sbIDevice.STATE_TRANSCODE) {
if (this._checkErrors(device)) {
devProperties.push("unsuccessful");
} else if (this._checkSuccess(device)){
devProperties.push("successful");
}
//if neither _checkErrors nor _checkSuccess is true, then the user
//cancelled before any successes or fails. Go back to idle image.
}
}
}
devNode.setAttributeNS(CDRIPNS, "LastState", device.state);
// Write back the device node properties.
devNode.className = devProperties.join(" ");
}
},
/**
* Get the devices library (defaults to first library)
* \param aDevice - Device to get library from
*/
_getDeviceLibrary: function sbCDRipServicePaneService__getDeviceLibrary(aDevice) {
// Get the libraries for device
var libraries = aDevice.content.libraries;
if (libraries.length < 1) {
// Oh no, we have no libraries
Cu.reportError("Device " + aDevice.id + " has no libraries!");
return null;
}
// Get the requested library
var deviceLibrary = libraries.queryElementAt(0, Ci.sbIMediaList);
if (!deviceLibrary) {
Cu.reportError("Unable to get library for device: " + aDevice.id);
return null;
}
return deviceLibrary;
},
/**
* Turn the read only flag for the library on or off. This allows us to disable
* changes to the CD Device library during a rip.
* \param aReadOnly - Mark as read only (Disable changes) if true.
* \param aDevice - CD Device to toggle read only.
*/
_toggleReadOnly: function sbCDRipServicePaneService__toggleReadOnly(aReadOnly,
aDevice) {
var deviceLibrary = this._getDeviceLibrary(aDevice);
if (deviceLibrary)
deviceLibrary.setProperty(SBProperties.isReadOnly,
(aReadOnly ? "1" : "0"));
},
/**
* Check for any ripped tracks that failed
* \param aDevice - Device to check
* \return True if errors occured, false otherwise
*/
_checkErrors: function sbCDRipServicePaneService__checkErrors(aDevice) {
// Check for any tracks that have a failed status
var deviceLibrary = this._getDeviceLibrary(aDevice);
var errorCount = 0;
try {
// Get all the did not successfully ripped tracks
var propArray =
Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"]
.createInstance(Ci.sbIMutablePropertyArray);
propArray.appendProperty(SBProperties.cdRipStatus, "3|100");
propArray.appendProperty(SBProperties.shouldRip, "1");
var rippedItems = deviceLibrary.getItemsByProperties(propArray);
errorCount = rippedItems.length;
}
catch (err if err.result == Cr.NS_ERROR_NOT_AVAILABLE) {
// deviceLibrary.getItemsByProperties() will throw NS_ERROR_NOT_AVAILABLE
// if there are no failed rips in the list, thus no errors.
return false;
}
catch (err) {
Cu.reportError("ERROR GETTING TRANSCODE ERROR COUNT " + err);
}
return (errorCount > 0);
},
/**
* Check if any tracks successfully ripped
* \param aDevice - Device to check
* \return True if at least one track was ripped, false otherwise
*/
_checkSuccess: function sbCDRipServicePaneService__checkErrors(aDevice) {
// Check if any tracks were successfully ripped
var deviceLibrary = this._getDeviceLibrary(aDevice);
var successCount = 0;
try {
var propArray = Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"]
.createInstance(Ci.sbIMutablePropertyArray);
propArray.appendProperty(SBProperties.cdRipStatus, "2|100");
propArray.appendProperty(SBProperties.shouldRip, "1");
var rippedItems = deviceLibrary.getItemsByProperties(propArray);
successCount = rippedItems.length;
}
catch (err if err.result == Cr.NS_ERROR_NOT_AVAILABLE) {
// deviceLibrary.getItemsByProperties() will throw NS_ERROR_NOT_AVAILABLE
// if there are no successful rips in the list.
return false;
}
catch (err) {
Cu.reportError("ERROR GETTING TRANSCODE SUCCESS COUNT " + err);
}
return (successCount > 0);
},
/**
* \brief Add a device that has media from event information.
* \param aDeviceEvent - Device event of added device.
*/
_addDeviceFromEvent:
function sbCDRipServicePaneService_addDeviceFromEvent(aDeviceEvent) {
var device = aDeviceEvent.data.QueryInterface(Ci.sbIDevice);
var deviceType = device.parameters.getProperty("DeviceType");
// We only care about CD devices
if (deviceType != "CD")
return false;
try {
this._addDevice(device);
}
catch(e) {
Cu.reportError(e);
return false;
}
return true;
},
/**
* \brief Remove a device that no longer has media from event information.
* \param aDeviceEvent - Device event of removed device.
*/
_removeDeviceFromEvent:
function sbCDRipServicePaneService_removeDeviceFromEvent(aDeviceEvent) {
var device = aDeviceEvent.data.QueryInterface(Ci.sbIDevice);
var deviceType = device.parameters.getProperty("DeviceType");
// We only care about CD devices
if (deviceType != "CD")
return;
try {
this._removeDevice(device);
}
catch(e) {
Cu.reportError(e);
}
},
/**
* \brief Add a device that has media.
* \param aDevice - Device to add, this will only be added if it is of type
* "CD".
*/
_addDevice: function sbCDRipServicePaneService_addDevice(aDevice) {
var device = aDevice.QueryInterface(Ci.sbIDevice);
var devId = device.id;
// Do nothing if device is not an CD device.
var deviceType = device.parameters.getProperty("DeviceType");
if (deviceType != "CD") {
return;
}
// Add a cd rip node in the service pane.
var devNode = this._deviceServicePaneSvc.createNodeForDevice2(device, true);
devNode.setAttributeNS(CDRIPNS, "DeviceId", devId);
devNode.setAttributeNS(CDRIPNS, "deviceNodeType", "cd-device");
devNode.className = "cd-device";
devNode.contractid = this._cfg.contractID;
devNode.url = this._cfg.devMgrURL + "?device-id=" + devId;
devNode.editable = false;
devNode.name = device.properties.friendlyName;
this._deviceInfoList[devId] = {svcPaneNode: devNode};
},
/**
* \brief Remove a known CD Device from the service pane.
* \param aDevice - Device to remove.
*/
_removeDevice: function sbCDRipServicePaneService_removeDevice(aDevice) {
var device = aDevice.QueryInterface(Ci.sbIDevice);
var devId = device.id;
var devInfo = this._deviceInfoList[devId];
if (!devInfo) {
return;
}
// Remove the device node.
devInfo.svcPaneNode.parentNode.removeChild(devInfo.svcPaneNode);
// Remove device info list entry.
delete this._deviceInfoList[devId];
}
};
// Instantiate an XPCOM module.
function NSGetModule(compMgr, fileSpec) {
return XPCOMUtils.generateModule([sbCDRipServicePaneService]);
}