sbIPDServicePaneService.js
Go to the documentation of this file.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2010 POTI, Inc.
9  * http://www.songbirdnest.com
10  *
11  * This file may be licensed under the terms of of the
12  * GNU General Public License Version 2 (the ``GPL'').
13  *
14  * Software distributed under the License is distributed
15  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
16  * express or implied. See the GPL for the specific language
17  * governing rights and limitations.
18  *
19  * You should have received a copy of the GPL along with this
20  * program. If not, go to http://www.gnu.org/licenses/gpl.html
21  * or write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  *=END SONGBIRD GPL
25  */
26 
32 //------------------------------------------------------------------------------
33 //------------------------------------------------------------------------------
34 //
35 // iPod device service pane services.
36 //
37 //------------------------------------------------------------------------------
38 //------------------------------------------------------------------------------
39 
40 //------------------------------------------------------------------------------
41 //
42 // iPod device service pane imported services.
43 //
44 //------------------------------------------------------------------------------
45 
46 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
47 Components.utils.import("resource://app/jsmodules/ArrayConverter.jsm");
48 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
49 
50 
51 //------------------------------------------------------------------------------
52 //
53 // iPod device service pane services defs.
54 //
55 //------------------------------------------------------------------------------
56 
57 if (typeof(Cc) == "undefined")
58  var Cc = Components.classes;
59 if (typeof(Ci) == "undefined")
60  var Ci = Components.interfaces;
61 if (typeof(Cr) == "undefined")
62  var Cr = Components.results;
63 
64 const TYPE_X_SB_TRANSFER_MEDIA_LIST = "application/x-sb-transfer-media-list";
65 const IPODSP_NS = "http://songbirdnest.com/rdf/ipod-servicepane#";
66 
67 
68 //------------------------------------------------------------------------------
69 //
70 // iPod device service pane services configuration.
71 //
72 //------------------------------------------------------------------------------
73 
74 //
75 // className Name of component class.
76 // cid Component CID.
77 // contractID Component contract ID.
78 // ifList List of external component interfaces.
79 // categoryList List of component categories.
80 //
81 // localeBundlePath Path to locale string bundle.
82 //
83 // devURNPrefix Device URN prefix.
84 // libURNPrefix Library URN prefix.
85 // itemURNPrefix Item URN prefix.
86 //
87 // appQuitTopic Application quit event observer topic.
88 //
89 // devImgURL URL of device service pane node image.
90 // devBusyImgURL URL of busy device service pane node image.
91 // devMgrURL URL of device manager window.
92 //
93 
94 var IPD_SPSCfg= {
95  className: "Songbird iPod Device Service Pane Service",
96  cid: Components.ID("{EC76F798-AB27-4B85-A2AD-0D794E0232F9}"),
97  contractID: "@songbirdnest.com/servicepane/IPodDevice;1",
98  ifList: [ Ci.sbIServicePaneModule,
99  Ci.nsIObserver,
100  Ci.sbIDeviceEventListener ],
101  categoryList:
102  [
103  {
104  category: "service-pane",
105  entry: "ipod-device"
106  }
107  ],
108 
109  localeBundlePath: "chrome://ipod/locale/IPodDevice.properties",
110 
111  devURNPrefix: "urn:device:",
112  libURNPrefix: "urn:library:",
113  itemURNPrefix: "urn:item:",
114 
115  devImgURL: "chrome://ipod/skin/icon_ipod_16x16.png",
116  devBusyImgURL: "chrome://songbird/skin/icons/icon-busy.png",
117  devMgrURL: "chrome://ipod/content/xul/iPodDeviceSummaryPage.xul"
118 };
119 
120 
121 //------------------------------------------------------------------------------
122 //
123 // iPod device service pane services.
124 //
125 //------------------------------------------------------------------------------
126 
127 // IPD_SPS
132 function IPD_SPS()
133 {
134 }
135 
136 /* Set the constructor. */
137 IPD_SPS.prototype.constructor = IPD_SPS;
138 
139 IPD_SPS.prototype = {
140  //
141  // iPod device service pane services fields.
142  //
143  // classDescription Description of component class.
144  // classID Component class ID.
145  // contractID Component contract ID.
146  // _xpcom_categories List of component categories.
147  //
148  // _cfg Configuration settings.
149  // _locale Locale string bundle.
150  // _observerSvc Observer service object.
151  // _devMgr Device manager object.
152  // _servicePaneSvc Service pane service object.
153  // _devServicePaneSvc Device service pane service object.
154  // _libServicePaneSvc Library service pane service object.
155  // _libMgr Library manager object.
156  // _devInfoList List of device information.
157  //
158 
159  classDescription: IPD_SPSCfg.className,
160  classID: IPD_SPSCfg.cid,
161  contractID: IPD_SPSCfg.contractID,
162  _xpcom_categories: IPD_SPSCfg.categoryList,
163 
164  _cfg: IPD_SPSCfg,
165  _locale: null,
166  _observerSvc: null,
167  _devMgr: null,
168  _servicePaneSvc: null,
169  _devServicePaneSvc: null,
170  _libServicePaneSvc: null,
171  _libMgr: null,
172  _devInfoList: null,
173 
174 
175  //----------------------------------------------------------------------------
176  //
177  // iPod device service pane sbIServicePaneModule services.
178  //
179  //----------------------------------------------------------------------------
180 
181  /* \brief Initialize this service pane module
182  * This is where the module should set itself up in the tree if it hasn't
183  * before.
184  * \param aServicePaneService the service pane service instance
185  */
186 
187  servicePaneInit: function IPD_SPS_servicePaneInit(aServicePaneService) {
188  // Save the service pane service.
189  this._servicePaneSvc = aServicePaneService;
190 
191  // Initialize the services.
192  this._initialize();
193  },
194 
195 
196  /* \brief Fill the context menu for the given node
197  * \param aNode the node that was context-clicked on
198  * \param aContextMenu the menu we're trying to fill
199  * \param aParentWindow the toplevel window we're displaying in
200  */
201 
202  fillContextMenu: function IPD_SPS_fillContextMenu(aNode,
203  aContextMenu,
204  aParentWindow) { },
205 
206 
207  /* \brief Fill a menu with menuitems to create new tree nodes
208  * \param aNode the node or null for the click and hold menu
209  * \param aContextMenu the menu we're trying to fill
210  * \param aParentWindow the toplevel window we're displaying in
211  */
212 
213  fillNewItemMenu: function IPD_SPS_fillNewItemMenu(aNode,
214  aContextMenu,
215  aParentWindow) { },
216 
217 
218  /* \brief Selection changes notification
219  * \param aNode the node that is now selected
220  * \param aParentWindow the toplevel window we're displaying in
221  */
222 
223  onSelectionChanged: function IPD_SPS_onSelectionChanged(aNode,
224  aContainer,
225  aParentWindow) { },
226 
227 
228  /* \brief Return whether the item can be dropped on the node
229  */
230 
231  canDrop: function IPD_SPS_canDrop(aNode,
232  aDragSession,
233  aOrientation,
234  aWindow) { },
235 
236 
237  /* \brief Handle dropping of an item on node
238  */
239 
240  onDrop: function IPD_SPS_onDrop(aNode, aDragSession, aOrientation, aWindow) {
241  },
242 
243 
244  /* \brief Handle drag gesture
245  */
246 
247  onDragGesture: function IPD_SPS_onDragGesture(aNode, aDataTransfer) { },
248 
249 
250  /* \brief Called before a user starts to rename a node.
251  * \param aNode the node that is about to be renamed
252  */
253 
254  onBeforeRename: function IPD_SPS_onBeforeRename(aNode) {
255  },
256 
257 
258  /* \brief Called when a node is renamed by the user, allows
259  * the module to accept the action by setting the
260  * node name to the given value.
261  * \param aNode the node that was renamed
262  * \param aNewName new name entered by the user
263  */
264 
265  onRename: function IPD_SPS_onRename(aNode, aNewName) {
266  // Get the device. Do nothing if not a device node.
267  var deviceID = aNode.getAttributeNS(IPODSP_NS, "device-id");
268  if (!deviceID)
269  return;
270  var deviceInfo = this._devInfoList[deviceID];
271  if (!deviceInfo)
272  return;
273  var device = deviceInfo.device;
274  if (!device)
275  return;
276 
277  // Set the new device name.
278  device.properties.friendlyName = aNewName;
279  },
280 
281 
282  /* \brief Called when the service pane service is shutting down
283  */
284  shutdown: function IPD_SPS_shutdown() {
285  // Do nothing, since we shut down on quit-application
286  },
287 
288 
289  //----------------------------------------------------------------------------
290  //
291  // iPod device service pane sbIDeviceEventListener services.
292  //
293  //----------------------------------------------------------------------------
294 
299  onDeviceEvent: function IPD_SPS_onDeviceEvent(aEvent) {
300  // Dispatch processing of the event.
301  switch(aEvent.type) {
302  case Ci.sbIDeviceEvent.EVENT_DEVICE_ADDED :
303  this._addDevice(aEvent.data.QueryInterface(Ci.sbIDevice));
304  break;
305 
306  case Ci.sbIDeviceEvent.EVENT_DEVICE_REMOVED :
307  this._removeDevice(aEvent.data.QueryInterface(Ci.sbIDevice));
308  break;
309 
310  case Ci.sbIDeviceEvent.EVENT_DEVICE_STATE_CHANGED :
311  this._updateDevState(aEvent.origin.QueryInterface(Ci.sbIDevice));
312  break;
313 
314  case Ci.sbIDeviceEvent.EVENT_DEVICE_INFO_CHANGED :
315  this._updateDevInfo(aEvent.origin.QueryInterface(Ci.sbIDevice));
316  break;
317 
318  default :
319  break;
320  }
321  },
322 
323 
324  //----------------------------------------------------------------------------
325  //
326  // iPod device service pane sbIMediaListListener services.
327  //
328  //----------------------------------------------------------------------------
329 
330  //
331  // _inBatchMap Map of media lists in a batch update.
332  // _rescanListMap Map of media lists to be rescanned.
333  //
334 
335  _inBatchMap: null,
336  _rescanListMap: null,
337 
338 
343  _sbIMLL_Initialize: function IPD_SPS__sbIMLL_Initialize() {
344  this._inBatchMap = { };
345  this._rescanListMap = { };
346  },
347 
348 
353  _sbIMLL_Finalize: function IPD_SPS__sbIMLL_Finalize() {
354  this._inBatchMap = null;
355  this._rescanListMap = null;
356  },
357 
358 
368  onItemAdded: function IPD_SPS_onItemAdded(aMediaList, aMediaItem, aIndex) {
369  var returnVal = false;
370  try { returnVal = this._onItemAdded(aMediaList, aMediaItem); }
371  catch (ex) { dump("onItemAdded exception: " + ex + "\n"); }
372  return (returnVal);
373  },
374 
375  _onItemAdded: function IPD_SPS__onItemAdded(aMediaList, aMediaItem) {
376  var noFurtherNotifications = false;
377 
378  // If in a batch, mark media list for rescanning. Otherwise, add any
379  // playlists to the device playlist maps.
380  if (this._inBatchMap[aMediaList.guid]) {
381  this._rescanListMap[aMediaList.guid] = true;
382  noFurtherNotifications = true;
383  } else {
384  if (aMediaItem instanceof Components.interfaces.sbIMediaList)
385  this._addDevPlaylist(aMediaItem);
386  }
387 
388  return noFurtherNotifications;
389  },
390 
391 
401  onBeforeItemRemoved: function IPD_SPS_onBeforeItemRemoved(aMediaList,
402  aMediaItem,
403  aIndex) {
404  var noFurtherNotifications = false;
405 
406  // If in a batch, mark media list for rescanning. Otherwise, remove any
407  // playlists from the device playlist maps.
408  if (this._inBatchMap[aMediaList.guid]) {
409  this._rescanListMap[aMediaList.guid] = true;
410  noFurtherNotifications = true;
411  } else {
412  if (aMediaItem instanceof Components.interfaces.sbIMediaList)
413  this._removeDevPlaylist(aMediaItem);
414  }
415 
416  return noFurtherNotifications;
417  },
418 
419 
429  onAfterItemRemoved: function IPD_SPS_onAfterItemRemoved(aMediaList,
430  aMediaItem,
431  aIndex) {
432  return true;
433  },
434 
435 
447  onItemUpdated: function IPD_SPS_onItemUpdated(aMediaList,
448  aMediaItem,
449  aIndex,
450  aProperties) {
451  return true;
452  },
453 
464  onBeforeListCleared: function IPD_SPS_onBeforeListCleared(aMediaList,
465  aExcludeLists) {
466  return true;
467  },
468 
479  onListCleared: function IPD_SPS_onListCleared(aMediaList,
480  aExcludeLists) {
481  var noFurtherNotifications = false;
482 
483  // If in a batch, mark media list for rescanning. Otherwise, update the
484  // device playlist maps.
485  if (this._inBatchMap[aMediaList.guid]) {
486  this._rescanListMap[aMediaList.guid] = true;
487  noFurtherNotifications = true;
488  } else {
489  this._updateDevPlaylists(aMediaList);
490  }
491 
492  return noFurtherNotifications;
493  },
494 
495 
507  onBatchBegin: function IPD_SPS_onBatchBegin(aMediaList) {
508  // Add media list to the in batch map.
509  this._inBatchMap[aMediaList.guid] = true;
510  },
511 
512 
524  onBatchEnd: function(aMediaList) {
525  // Remove media list from the in batch map.
526  delete this._inBatchMap[aMediaList.guid];
527 
528  // Update device playlists if needed.
529  if (this._rescanListMap[aMediaList.guid]) {
530  this._updateDevPlaylists(aMediaList);
531  delete(this._rescanListMap[aMediaList.guid]);
532  }
533  },
534 
535 
536  //----------------------------------------------------------------------------
537  //
538  // iPod device service pane nsIObserver services.
539  //
540  //----------------------------------------------------------------------------
541 
550  observe: function IPD_SPS_observe(aSubject, aTopic, aData) {
551  try { this._observe(aSubject, aTopic, aData); }
552  catch (ex) { dump("observe exception: " + ex + "\n"); }
553  },
554 
555  _observe: function IPD_SPS__observe(aSubject, aTopic, aData) {
556  // Dispatch processing of the event.
557  switch (aTopic) {
558  case "quit-application" :
559  this._handleAppQuit();
560  break;
561  }
562  },
563 
564 
565  //----------------------------------------------------------------------------
566  //
567  // iPod device service pane nsISupports services.
568  //
569  //----------------------------------------------------------------------------
570 
571  QueryInterface: XPCOMUtils.generateQI(IPD_SPSCfg.ifList),
572 
573 
574  //----------------------------------------------------------------------------
575  //
576  // iPod device service pane event handling services.
577  //
578  //----------------------------------------------------------------------------
579 
584  _handleAppQuit: function IPD_SPS__handleAppQuit() {
585  // Finalize the services.
586  this._finalize();
587  },
588 
589 
590  //----------------------------------------------------------------------------
591  //
592  // iPod device service pane services.
593  //
594  //----------------------------------------------------------------------------
595 
600  _initialize: function IPD_SPS__initialize() {
601  // Initialize the device lists and maps.
602  this._devInfoList = {};
603 
604  // Get the locale string bundle.
605  var stringBundleSvc = Cc["@mozilla.org/intl/stringbundle;1"]
606  .getService(Ci.nsIStringBundleService);
607  this._locale = stringBundleSvc.createBundle(this._cfg.localeBundlePath);
608 
609  // Set up observers.
610  this._observerSvc = Cc["@mozilla.org/observer-service;1"]
611  .getService(Ci.nsIObserverService);
612  this._observerSvc.addObserver(this, "quit-application", false);
613 
614  // Get the library manager.
615  this._libMgr = Cc["@songbirdnest.com/Songbird/library/Manager;1"]
616  .getService(Ci.sbILibraryManager);
617 
618  // Get the device manager and device and library service pane services.
619  this._devMgr = Cc["@songbirdnest.com/Songbird/DeviceManager;2"]
620  .getService(Ci.sbIDeviceManager2);
621  this._devServicePaneSvc = Cc["@songbirdnest.com/servicepane/device;1"]
622  .getService(Ci.sbIDeviceServicePaneService);
623  this._libServicePaneSvc = Cc["@songbirdnest.com/servicepane/library;1"]
624  .getService(Ci.sbILibraryServicePaneService);
625 
626  // Initialize the sbIMediaListListener services.
627  this._sbIMLL_Initialize();
628 
629  // Add device event listener.
630  this._devMgr.addEventListener(this);
631 
632  // Add all connected devices.
633  this._addAllConnectedDevices();
634  },
635 
636 
641  _finalize: function IPD_SPS__finalize() {
642  // Remove observers.
643  this._observerSvc.removeObserver(this, "quit-application");
644 
645  // Remove device event listener.
646  this._devMgr.removeEventListener(this);
647 
648  // Finalize the sbIMediaListListener services.
649  this._sbIMLL_Finalize();
650 
651  // Remove all devices.
652  this._removeAllDevices();
653 
654  // Clear the device lists
655  this._devInfoList = null;
656 
657  // Clear object references.
658  this._observerSvc = null;
659  this._devMgr = null;
660  this._servicePaneSvc = null;
661  this._libServicePaneSvc = null;
662  },
663 
669  _findDevInfoForDevLib : function sbMSC_SPS_servicePaneInit(aDevLibId) {
670  for (prop in this._devInfoList) {
671  var devInfo = this._devInfoList[prop];
672  if (devInfo && devInfo.devLibId == aDevLibId) {
673  return devInfo;
674  }
675  }
676  return null;
677  },
678 
685  _addDevice: function IPD_SPS__addDevice(aDevice) {
686  // Do nothing if device has already been added.
687  var deviceID = aDevice.id;
688  if (this._devInfoList[deviceID])
689  return;
690 
691  // Do nothing if device is not an iPod.
692  if (aDevice.parameters.getProperty("DeviceType") != "iPod")
693  return;
694 
695  // Do nothing if device is not connected.
696  if (!aDevice.connected)
697  return;
698 
699  // Create a device info list entry.
700  this._devInfoList[deviceID] = {};
701  this._devInfoList[deviceID].playlistList = {};
702  this._devInfoList[deviceID].device = aDevice;
703 
704  // Add a device node in the service pane.
705  var devNode = this._devServicePaneSvc.createNodeForDevice2(aDevice, true);
706  devNode.setAttributeNS(IPODSP_NS, "device-id", deviceID);
707  devNode.contractid = this._cfg.contractID;
708  devNode.name = aDevice.properties.friendlyName;
709  devNode.image = this._cfg.devImgURL;
710  devNode.hidden = false;
711  devNode.url = this._cfg.devMgrURL + "?device-id=" + deviceID;
712  devNode.editable = true;
713  this._devInfoList[deviceID].svcPaneNode = devNode;
714 
715  // Fill device node context menu with default items.
716  this._devServicePaneSvc.setFillDefaultContextMenu(devNode, true);
717 
718  // Add the device library. Use the raw library instead of the
719  // sbIDeviceLibrary since the sbIDeviceLibrary is mostly useless in the
720  // device removal events.
721  var devLib;
722  try
723  {
724  devLib = aDevice.content.libraries.queryElementAt(0, Ci.sbILibrary);
725  devLib = this._libMgr.getLibrary(devLib.guid);
726  } catch (ex) {}
727  if (devLib)
728  this._addDevLib(devLib, aDevice);
729 
730  // Update the device playlists.
731  if (devLib)
732  this._updateDevPlaylists(devLib);
733  },
734 
735 
742  _removeDevice: function IPD_SPS__removeDevice(aDevice) {
743  // Get the device info. Do nothing if no device info available.
744  var device = aDevice.QueryInterface(Ci.sbIDevice);
745  var deviceID = device.id;
746  var devInfo = this._devInfoList[deviceID];
747  if (!devInfo)
748  return;
749 
750  // Remove the device library.
751  if (devInfo.devLibId)
752  this._removeDevLib(aDevInfo);
753 
754  // Remove the device node.
755  if (devInfo.svcPaneNode) {
756  this._servicePaneSvc.removeNode(devInfo.svcPaneNode);
757  }
758 
759  // Remove device info list entry.
760  delete this._devInfoList[deviceID];
761  },
762 
763 
768  _addAllConnectedDevices: function IPD_SPS__addAllConnectedDevices() {
769  var deviceList = ArrayConverter.JSArray(this._devMgr.devices);
770  for each (device in deviceList) {
771  this._addDevice(device.QueryInterface(Ci.sbIDevice));
772  }
773  },
774 
775 
780  _removeAllDevices: function IPD_SPS__removeAllDevices() {
781  // Remove all devices.
782  for (var deviceID in this._devInfoList)
783  this._removeDevice(this._devInfoList[deviceID].device);
784  },
785 
786 
795  _addDevLib: function IPD_SPS__addDevLib(aLibrary, aDevice) {
796  // Get the device ID.
797  var deviceID = aDevice.id;
798 
799  // Save of the device library's ID.
800  this._devInfoList[deviceID].devLibId = aLibrary.guid;
801 
802  // Create the device library service pane node.
803  var devLibNode = this._devServicePaneSvc
804  .createLibraryNodeForDevice(aDevice, aLibrary);
805  this._devInfoList[deviceID].devLibNode = devLibNode;
806 
807  // Fill device library node context menu with default items.
808  this._devServicePaneSvc.setFillDefaultContextMenu(devLibNode, true);
809 
810  // Set the read-only property for the device library node.
811  this._setNodeReadOnly(aDevice, devLibNode);
812 
813  // Add a listener for the device library.
814  aLibrary.addListener(this,
815  false,
816  Ci.sbIMediaList.LISTENER_FLAGS_ALL &
817  ~Ci.sbIMediaList.LISTENER_FLAGS_ITEMUPDATED);
818  },
819 
820 
828  _removeDevLib: function IPD_SPS__removeDevLib(aDevInfo) {
829 
830  // Get library from GUID. It may not be available if it's already been
831  // removed.
832  var library;
833  try {
834  library = this._libMgr.getLibrary(aDevInfo.devLibId);
835  // Remove the device library listener
836  if (library) {
837  library.removeListener(this);
838  }
839  } catch (ex) {}
840  },
841 
842 
850  _addDevPlaylist: function IPD_SPS__addDevPlaylist(aMediaList) {
851  // Get the device info and playlist URN.
852  var devInfo = this._findDevInfoForDevLib(aMediaList.library.guid);
853  var playlistURN = this._cfg.itemURNPrefix + aMediaList.guid;
854 
855  var device = devInfo.device;
856 
857  // Do nothing if playlist already added.
858  if (devInfo.playlistList[playlistURN])
859  return;
860 
861  // Get the playlist service pane node, creating one if necessary.
862  var playlistNode = this._libServicePaneSvc
863  .getNodeForLibraryResource(aMediaList);
864  if (!playlistNode) {
865  playlistNode = this._servicePaneSvc.addNode(playlistURN,
866  this._servicePaneSvc.root,
867  true);
868  }
869 
870  // Set the read-only property for the playlist node.
871  this._setNodeReadOnly(device, playlistNode);
872 
873  // Move the playlist service pane node underneath the device service pane
874  // node.
875  devInfo.svcPaneNode.appendChild(playlistNode);
876 
877  // Add the playlist to the device playlist list.
878  devInfo.playlistList[playlistURN] = playlistNode;
879  },
880 
881 
889  _removeDevPlaylist: function IPD_SPS__removeDevPlaylist(aMediaList) {
890  // Remove the playlist from the device playlist list.
891  var devInfo = this._findDevInfoForDevLib(aMediaList.library.guid);
892  var playlistURN = this._cfg.itemURNPrefix + aMediaList.guid;
893  delete devInfo.playlistList[playlistURN];
894  },
895 
896 
904  _updateDevState: function IPD_SPS__updateDevState(aDevice) {
905  // Get the device node.
906  if (!this._devInfoList[aDevice.id])
907  return;
908  var devNode = this._devInfoList[aDevice.id].svcPaneNode;
909 
910  // Get the list of device node properties.
911  devNodePropList = devNode.properties.split(" ");
912 
913  // Update the device node busy property.
914  devNodePropList = devNodePropList.filter
915  (function(aProperty) { return aProperty != "busy"; });
916  if (aDevice.state != Ci.sbIDevice.STATE_IDLE)
917  devNodePropList.push("busy");
918 
919  // Determine whether or not the device is read-only
920  var deviceProperties = aDevice.properties.properties;
921  var accessCompatibility = deviceProperties.getPropertyAsAString(
922  "http://songbirdnest.com/device/1.0#accessCompatibility");
923  if (accessCompatibility == "ro") {
924  devNodePropList = devNodePropList.filter
925  (function(aProperty) { return aProperty != "read-only"; });
926  devNodePropList.push("read-only");
927  }
928 
929  // Update the device node image.
930  if (aDevice.state == Ci.sbIDevice.STATE_IDLE)
931  devNode.image = this._cfg.devImgURL;
932  else
933  devNode.image = null;
934 
935  // Write the device node properties.
936  devNode.properties = devNodePropList.join(" ");
937  },
938 
939 
947  _updateDevInfo: function IPD_SPS__updateDevInfo(aDevice) {
948 
949  var devInfo = this._devInfoList[aDevice.id];
950 
951  // Not our device, let someone else handle it.
952  if(!devInfo) {
953  return;
954  }
955 
956  devInfo.svcPaneNode.name = aDevice.properties.friendlyName;
957  },
958 
959 
967  _updateDevPlaylists: function IPD_SPS__updateDevPlaylists(aMediaList) {
968  // Set up an enumeration listener to collect items into a simple array.
969  var enumListener = {
970  itemList: [],
971  onEnumerationBegin: function() { },
972  onEnumerationEnd: function() { },
973  onEnumeratedItem: function(aList, aItem) {
974  this.itemList.push(aItem);
975  }
976  };
977 
978  // Create a list of media lists.
979  aMediaList.enumerateItemsByProperty(SBProperties.isList, "1", enumListener);
980 
981  // Add each media list as a device playlist.
982  var length = enumListener.itemList.length;
983  for (var i = 0; i < length; i++) {
984  this._addDevPlaylist(enumListener.itemList[i]);
985  }
986  },
987 
988 
998  _setNodeReadOnly: function IPD_SPS__setNodeReadOnly(aDevice, aNode) {
999  //XXXeps implement
1000  }
1001 };
1002 
1003 
1004 //------------------------------------------------------------------------------
1005 //
1006 // iPod device service pane services component services.
1007 //
1008 //------------------------------------------------------------------------------
1009 
1010 function NSGetModule(compMgr, fileSpec) {
1011  return XPCOMUtils.generateModule([IPD_SPS]);
1012 }
1013 
classDescription entry
Definition: FeedWriter.js:1427
const Cc
sbLibraryImporterManagerCfg categoryList
sbOSDControlService prototype className
function NSGetModule(compMgr, fileSpec)
function IPD_SPS()
Construct an iPod device service pane services object.
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
sbDownloadDeviceServicePaneModule prototype shutdown
var IPD_SPSCfg
sbDeviceServicePane prototype servicePaneInit
return null
Definition: FeedWriter.js:1143
const IPODSP_NS
const Cr
const Ci
sbDeviceFirmwareAutoCheckForUpdate prototype classID
sbWindowsAutoPlayServiceCfg _xpcom_categories
const TYPE_X_SB_TRANSFER_MEDIA_LIST
_getSelectedPageStyle s i
_updateTextAndScrollDataForFrame aData
sbDeviceFirmwareAutoCheckForUpdate prototype observe