deviceInfo.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 // Device info widget.
36 //
37 //------------------------------------------------------------------------------
38 //------------------------------------------------------------------------------
39 
40 //------------------------------------------------------------------------------
41 //
42 // Device info imported services.
43 //
44 //------------------------------------------------------------------------------
45 
46 // Component manager defs.
47 if (typeof(Cc) == "undefined")
48  var Cc = Components.classes;
49 if (typeof(Ci) == "undefined")
50  var Ci = Components.interfaces;
51 if (typeof(Cr) == "undefined")
52  var Cr = Components.results;
53 if (typeof(Cu) == "undefined")
54  var Cu = Components.utils;
55 
56 // Songbird imports.
57 Cu.import("resource://app/jsmodules/DOMUtils.jsm");
58 Cu.import("resource://app/jsmodules/SBTimer.jsm");
59 
60 
61 //------------------------------------------------------------------------------
62 //
63 // Device info defs.
64 //
65 //------------------------------------------------------------------------------
66 
67 // DOM defs.
68 if (typeof(XUL_NS) == "undefined")
69  var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
70 
71 
72 //------------------------------------------------------------------------------
73 //
74 // Device info services.
75 //
76 //------------------------------------------------------------------------------
77 
78 var DIW = {
79  //
80  // Device info configuration.
81  //
82  // _pollPeriodTable Table of polling periods for device information
83  // that needs to be polled.
84  // _contextMenuDocURL URL to context menu document.
85  //
86 
87  _pollPeriodTable: { "battery": 60000, "firmware_version": 60000 },
88  _contextMenuDocURL:
89  "chrome://songbird/content/xul/device/deviceContextMenu.xul",
90 
91 
92  //
93  // Device info object fields.
94  //
95  // _widget Device info widget.
96  // _device Device bound to widget.
97  // _deviceProperties Device properties.
98  // _deviceLibrary Bound device library.
99  // _contextMenuEnabled If true, the context menu is enabled.
100  // _contextMenuPopup Context menu popup.
101  //
102 
103  _widget: null,
104  _device: null,
105  _deviceProperties: null,
106  _deviceLibrary: null,
107  _contextMenuEnabled: false,
108  _contextMenuPopup: null,
109 
110 
118  initialize: function DIW__initialize(aWidget) {
119  // Get the device info widget.
120  this._widget = aWidget;
121 
122  // Initialize object fields.
123  this._device = this._widget.device;
124  this._deviceProperties = this._device.properties;
125  this._deviceLibrary = this._widget.devLib;
126 
127  // Initialize the context menu.
128  this._initializeContextMenu();
129 
130  // Show specified elements.
131  this._showElements();
132 
133  // Hide labels if needed
134  this._hideLabels();
135 
136  // Initialize the device spec rows.
137  this._deviceSpecInitialize();
138 
139  // Update the UI.
140  this._update();
141 
142  // Watch for device changes
143  this._device.QueryInterface(Ci.sbIDeviceEventTarget).addEventListener(this);
144  },
145 
146  onDeviceEvent : function DIW_onDeviceEvent(anEvent) {
147  if (anEvent.type == Ci.sbIDeviceEvent.EVENT_DEVICE_INFO_CHANGED) {
148  this._update();
149  }
150  },
155  finalize: function DIW_finalize() {
156  // Finalize the polling services.
157  this._pollingFinalize();
158 
159  // Stop listening
160  if (this._device != null) {
161  this._device.QueryInterface(Ci.sbIDeviceEventTarget)
162  .removeEventListener(this);
163  }
164 
165  // Finalize the device services.
166  this._deviceFinalize();
167 
168  // Clear object fields.
169  this._widget = null;
170  this._deviceLibrary = null;
171  this._contextMenuPopup = null;
172  },
173 
174 
175  //----------------------------------------------------------------------------
176  //
177  // Device info device spec row services.
178  //
179  // NOTE: These services may move the device spec rows within the document.
180  // Doing so disables the use of certain XUL element properties such as
181  // value. Thus, attributes must be used instead of properties.
182  //
183  //----------------------------------------------------------------------------
184 
190  _deviceSpecInitialize: function DIW__deviceSpecInitialize() {
191  // Get the list of device specs to present.
192  var deviceSpecs = this._widget.getAttribute("devicespecs");
193  var deviceSpecList = deviceSpecs.split(",");
194 
195  // Get the list of device spec row elements.
196  var deviceSpecRows = this._getElement("device_spec_rows");
197  var deviceSpecRowList = deviceSpecRows.getElementsByTagNameNS(XUL_NS,
198  "row");
199 
200  // Hide all device spec rows.
201  for (var i = 0; i < deviceSpecRowList.length; i++) {
202  deviceSpecRowList[i].hidden = true;
203  }
204 
205  // Move and update specified device spec rows into position. Also determine
206  // the device info polling period.
207  var pollPeriod = Number.POSITIVE_INFINITY;
208  var refDeviceSpecRow = deviceSpecRows.firstChild;
209  for (var i = 0; i < deviceSpecList.length; i++) {
210  // Get the device spec and row.
211  var deviceSpec = deviceSpecList[i];
212  var deviceSpecRow = this._getDeviceSpecRow(deviceSpec);
213 
214  // Skip device spec if it's not supported.
215  if (!this._supportsDeviceSpec(deviceSpec))
216  continue;
217 
218  // Move the device spec row into position.
219  if (deviceSpecRow != refDeviceSpecRow) {
220  deviceSpecRows.insertBefore(deviceSpecRow, refDeviceSpecRow);
221  }
222  refDeviceSpecRow = deviceSpecRow.nextSibling;
223 
224  // Show the device spec row.
225  deviceSpecRow.hidden = false;
226 
227  // Check the device spec polling period.
228  var specPollPeriod = this._pollPeriodTable[deviceSpec];
229  if (specPollPeriod && (specPollPeriod < pollPeriod))
230  pollPeriod = specPollPeriod;
231  }
232 
233  // Start polling if needed.
234  if (pollPeriod != Number.POSITIVE_INFINITY)
235  this._pollingInitialize(pollPeriod);
236  },
237 
238 
243  _deviceSpecUpdateAll: function DIW__deviceSpecUpdateAll() {
244  // Update all of the shown device spec rows.
245  var deviceSpecRows = this._getElement("device_spec_rows");
246  var deviceSpecRowList = deviceSpecRows.getElementsByTagNameNS
247  ("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
248  "row");
249  for (var i = 0; i < deviceSpecRowList.length; i++) {
250  var deviceSpecRow = deviceSpecRowList[i];
251  if (!deviceSpecRow.hidden)
252  this._deviceSpecUpdate(deviceSpecRow);
253  }
254  },
255 
256 
263  _deviceSpecUpdate: function DIW__deviceSpecUpdate(aRow) {
264  // Dispatch updating.
265  var deviceSpec = aRow.getAttribute("devicespec");
266  switch (deviceSpec) {
267  case "model" :
268  this._deviceSpecUpdateValue(aRow,
269  "model_value_label",
270  this._getDeviceModel());
271  break;
272 
273  case "capacity" :
274  this._deviceSpecUpdateValue(aRow,
275  "capacity_value_label",
276  this._getDeviceModelSize());
277  break;
278 
279  case "model_capacity" :
280  this._deviceSpecUpdateModelCapacity(aRow);
281  break;
282 
283  case "product_capacity" :
284  this._deviceSpecUpdateProductCapacity(aRow);
285  break;
286 
287  case "friendly_name" :
288  this._deviceSpecUpdateValue(aRow,
289  "friendly_name_value_label",
290  this._getDeviceFriendlyName());
291  break;
292 
293  case "serial_number" :
294  this._deviceSpecUpdateValue(aRow,
295  "serial_number_value_label",
296  this._getDeviceSerialNumber());
297  break;
298 
299  case "vendor" :
300  this._deviceSpecUpdateValue(aRow,
301  "vendor_value_label",
302  this._getDeviceVendor());
303  break;
304 
305  case "access" :
306  this._deviceSpecUpdateValue(aRow,
307  "access_value_label",
308  this._getDeviceAccessCompatibilityDesc());
309  break;
310 
311  case "playback_formats" :
312  this._deviceSpecUpdateDesc(aRow,
313  "playback_formats_value_label",
314  this._getDevicePlaybackFormats());
315  break;
316 
317  case "battery" :
318  this._deviceSpecUpdateBattery(aRow);
319  break;
320 
321  case "firmware_version":
322  this._deviceSpecUpdateValue(aRow,
323  "firmware_version_value_label",
324  this._getDeviceFirmwareVersion());
325  break;
326 
327  default :
328  break;
329  }
330  },
331 
332 
343  _deviceSpecUpdateValue: function DIW__deviceSpecUpdateValue(aRow,
344  aLabelID,
345  aValue) {
346  // Set the row no value attribute.
347  if (aValue && aRow.hasAttribute("novalue"))
348  aRow.removeAttribute("novalue");
349  else if (!aValue && (aRow.getAttribute("novalue") != "true"))
350  aRow.setAttribute("novalue", true);
351 
352  // Set the value label.
353  var labelElem = this._getElement(aLabelID);
354  if (labelElem.getAttribute("value") != aValue)
355  labelElem.setAttribute("value", aValue);
356  },
357 
358 
370  _deviceSpecUpdateDesc: function DIW__deviceSpecUpdateDesc(aRow,
371  aDescID,
372  aText) {
373  // Set the row no value attribute.
374  if (aText && aRow.hasAttribute("novalue"))
375  aRow.removeAttribute("novalue");
376  else if (!aText && (aRow.getAttribute("novalue") != "true"))
377  aRow.setAttribute("novalue", true);
378 
379  // Set the description text.
380  var descElem = this._getElement(aDescID);
381  if (descElem.firstChild.data != aText)
382  descElem.firstChild.data = aText;
383  },
384 
385 
392  _deviceSpecUpdateModelCapacity: function
393  DIW__deviceSpecUpdateModelCapacity(aRow) {
394  // Get the device model and model capacity.
395  var devModelValue = this._getDeviceModel();
396  var devCapValue = this._getDeviceModelSize();
397  var devModelCapValue = devModelValue + " (" + devCapValue + ")";
398 
399  // Upate the device model/capacity.
400  this._deviceSpecUpdateValue(aRow,
401  "model_capacity_value_label",
402  devModelCapValue);
403  },
404 
405 
412  _deviceSpecUpdateProductCapacity: function
413  DIW__deviceSpecUpdateProductCapacity(aRow) {
414  // Get the device product name
415  var devProductValue = this._getDeviceProduct();
416 
417  // Get the device capacity.
418  var capacity = "";
419  if (this._deviceLibrary) {
420  try {
421  storageConverter =
422  Cc["@songbirdnest.com/Songbird/Properties/UnitConverter/Storage;1"]
423  .createInstance(Ci.sbIPropertyUnitConverter);
424  capacity = this._deviceLibrary.getProperty
425  ("http://songbirdnest.com/device/1.0#capacity");
426  capacity = storageConverter.autoFormat(capacity, -1, 1);
427  } catch (ex) {};
428  }
429 
430  var devProductCapValue = SBFormattedString("device.info.product_cap",
431  [ devProductValue, capacity ]);
432 
433  // Upate the device model/capacity.
434  this._deviceSpecUpdateValue(aRow,
435  "product_capacity_value_label",
436  devProductCapValue);
437  },
438 
439 
446  _deviceSpecUpdateBattery: function DIW__deviceSpecUpdateBattery(aRow) {
447  // Get the battery status.
448  var batteryLevel = {};
449  var onBatteryPower = {};
450  this._getDeviceBatteryStatus(batteryLevel, onBatteryPower);
451  batteryLevel = batteryLevel.value;
452  onBatteryPower = onBatteryPower.value;
453  var batteryStatus;
454  if (onBatteryPower)
455  batteryStatus = "battery-powered";
456  else if (batteryLevel == 100)
457  batteryStatus = "charged";
458  else
459  batteryStatus = "charging";
460 
461  // Update the battery status and level.
462  var batteryElem = this._getElement("battery_status");
463  if (batteryLevel == -1) {
464  batteryElem.hidden = true;
465  }
466  else {
467  batteryElem.hidden = false;
468  if ((batteryElem.getAttribute("status") != batteryStatus) ||
469  (batteryElem.getAttribute("level") != batteryLevel)) {
470  batteryElem.setAttribute("status", batteryStatus);
471  batteryElem.setAttribute("level", batteryLevel);
472  }
473  }
474  },
475 
476 
477  //----------------------------------------------------------------------------
478  //
479  // Device info context menu services.
480  //
481  //----------------------------------------------------------------------------
482 
487  _initializeContextMenu: function DIW__initializeContextMenu() {
488  // Check if the context menu is enabled. Do nothing more if not.
489  if (this._widget.getAttribute("enable_context_menu") == "true") {
490  this._contextMenuEnabled = true;
491  } else {
492  this._contextMenuEnabled = false;
493  return;
494  }
495 
496  // Get the content menu popup and clear it.
497  this._contextMenuPopup = this._getElement("context_menu_popup");
498  while (this._contextMenuPopup.hasChildNodes()) {
499  this._contextMenuPopup.removeChild(this._contextMenuPopup.firstChild);
500  }
501 
502  // Import the device context menu items.
503  var deviceContextMenuDoc = DOMUtils.loadDocument(this._contextMenuDocURL);
504  DOMUtils.importChildElements(this._contextMenuPopup,
505  deviceContextMenuDoc,
506  "device_context_menu_items",
507  { "device-id": this._device.id });
508  },
509 
510 
517  onContextMenu: function DIW_onContextMenu(aEvent) {
518  // Do nothing if context menu is not enabled.
519  if (!this._contextMenuEnabled)
520  return;
521 
522  // Open the context menu popup.
523  this._contextMenuPopup.openPopup(null,
524  null,
525  aEvent.clientX,
526  aEvent.clientY,
527  true,
528  false);
529  },
530 
531 
532  //----------------------------------------------------------------------------
533  //
534  // Device info XUL services.
535  //
536  //----------------------------------------------------------------------------
537 
547  _getElement: function DIW__getElement(aElementID) {
548  return document.getAnonymousElementByAttribute(this._widget,
549  "sbid",
550  aElementID);
551  },
552 
553 
563  _getDeviceSpecRow: function DIW__getDeviceSpecRow(aDeviceSpec) {
564  return document.getAnonymousElementByAttribute(this._widget,
565  "devicespec",
566  aDeviceSpec);
567  },
568 
569 
578  _getShowElement: function DIW__getShowElement(aShowID) {
579  return document.getAnonymousElementByAttribute(this._widget,
580  "showid",
581  aShowID);
582  },
583 
584 
585  //----------------------------------------------------------------------------
586  //
587  // Device info polling services.
588  //
589  //----------------------------------------------------------------------------
590 
591  //
592  // Device info polling services fields.
593  //
594  // _pollingTimer Timer used for polling device info.
595  //
596 
597  _pollingTimer: null,
598 
599 
607  _pollingInitialize: function DIW__pollingInitialize(aPollPeriod) {
608  // Start a timing interval to poll for device info UI updates.
609  var _this = this;
610  var func = function() { _this._update(); }
611  this._pollingTimer = new SBTimer(func,
612  aPollPeriod,
613  Ci.nsITimer.TYPE_REPEATING_SLACK);
614  },
615 
616 
621  _pollingFinalize: function DIW__pollingFinalize() {
622  if (this._pollingTimer) {
623  this._pollingTimer.cancel();
624  this._pollingTimer = null;
625  }
626  },
627 
628 
629  //----------------------------------------------------------------------------
630  //
631  // Internal device info services.
632  //
633  //----------------------------------------------------------------------------
634 
639  _hideLabels: function DIW__hideLabels() {
640  if (this._widget.getAttribute("hidelabels")) {
641  this._getElement("device_specs_label_column").hidden = true;
642 
643  // Hide the labels
644  var gridRows = this._getElement("device_spec_rows");
645 
646  // Each child of the <rows> is a <row> where the firstChild is
647  // the label for product/model/etc.
648  var rowElements = gridRows.getElementsByTagNameNS(XUL_NS, "row");
649  for each (var row in rowElements) {
650  if (row.firstChild)
651  row.firstChild.hidden = true;
652  }
653  }
654  },
655 
660  _showElements: function DIW__showElements() {
661  // Get the list of elements to show.
662  var showListAttr = this._widget.getAttribute("showlist");
663  if (!showListAttr)
664  return;
665  var showList = this._widget.getAttribute("showlist").split(",");
666 
667  // Show the specified elements.
668  for (var i = 0; i < showList.length; i++) {
669  var element = this._getShowElement(showList[i]);
670  element.hidden = false;
671  if (element.parentNode.hidden)
672  element.parentNode.hidden = false;
673  }
674  },
675 
676 
682  _update: function DIW__update() {
683  // Update the device name label.
684  var devNameLabel = this._getElement("device_name_label");
685  var devName = this._getDeviceName();
686  if (devNameLabel.value != devName)
687  devNameLabel.value = devName;
688 
689  // Update the device image.
690  var devImage = this._getElement("device_image");
691  var devIconURL = this._getDeviceIcon();
692  if (devIconURL && (devImage.src != devIconURL))
693  devImage.src = devIconURL;
694 
695  // If the device is read-only, then unhide the read-only lock icon
696  // but only do it if the device image is also visible
697  if (!devImage.hidden) {
698  var lockImage = this._getElement("device_image_ro");
699  var accessCompatibility = this._getDeviceAccessCompatibility();
700  if (accessCompatibility == "ro")
701  lockImage.hidden = false;
702  }
703 
704  // Update the device specs.
705  this._deviceSpecUpdateAll();
706  },
707 
708 
709  //----------------------------------------------------------------------------
710  //
711  // Device info device services.
712  //
713  // These services provide an interface to the device object.
714  // These services register for any pertinent device notifications and call
715  // _update to update the UI accordingly. These include notifications for
716  // changes to the device friendly name.
717  //
718  //----------------------------------------------------------------------------
719 
720  //
721  // Device info services fields.
722  //
723  // _lastPropertyValue Holds the last value retrieved in case we
724  // can't retrieve the property due to formatting
725  // or other reasons
726 
727  _lastPropertyValue : {},
728 
733  _deviceFinalize: function DIW__deviceFinalize() {
734  // Clear object fields.
735  this._device = null;
736  },
737 
749  _getDeviceProperty: function DIW__getDeviceProperty(aPropertyName, aDefault) {
750  try {
751  if (this._deviceProperties.properties.hasKey(aPropertyName)) {
752  let value = this._deviceProperties.properties.getPropertyAsAString(
753  aPropertyName);
754  this._lastPropertyValue[aPropertyName] = value;
755  return value;
756  }
757  } catch (err) {
758  if (this._lastPropertyValue[aPropertyName]) {
759  return this._lastPropertyValue[aPropertyName];
760  }
761  }
762  return aDefault;
763  },
764 
771  _getDeviceModel: function DIW__getDeviceModel() {
772  var modelNumber = null;
773  try {
774  modelNumber = this._deviceProperties.modelNumber;
775  this._lastPropertyValue.modelNumber = modelNumber;
776  }
777  catch(err) {
778  if (this._lastPropertyValue.modelNumber) {
779  modelNumber = this._lastPropertyValues.modelNumber;
780  }
781  }
782  if (modelNumber == null)
783  modelNumber = SBString("device.info.unknown");
784 
785  return modelNumber;
786  },
787 
794  _getDeviceProduct: function DIW__getDeviceProduct() {
795  var productName = null;
796  try {
797  productName = this._device.productName;
798  this._lastPropertyValue.productName = productName;
799  } catch(err) {
800  if (this._lastPropertyValue.productName) {
801  productName = this._lastPropertyValue.productName;
802  }
803  }
804  if (productName == null)
805  productName = SBString("device.info.unknown");
806  return productName;
807  },
808 
809 
816  _getDeviceModelSize: function DIW__getDeviceModelSize() {
817  if (this._deviceLibrary) {
818  try {
819  storageConverter =
820  Cc["@songbirdnest.com/Songbird/Properties/UnitConverter/Storage;1"]
821  .createInstance(Ci.sbIPropertyUnitConverter);
822  var modelSize = this._deviceLibrary.getProperty
823  ("http://songbirdnest.com/device/1.0#capacity");
824  return storageConverter.autoFormat(modelSize, -1, 1);
825  } catch (err) { }
826  }
827 
828  return SBString("device.info.unknown");
829  },
830 
831 
838  _getDeviceName: function DIW__getDeviceName() {
839  var name = null;
840  try { name = this._device.name; } catch(err) {}
841  if (name == null)
842  name = SBString("device.info.unknown");
843 
844  return name;
845  },
846 
847 
854  _getDeviceFriendlyName: function DIW__getDeviceFriendlyName() {
855  var friendlyName = null;
856  try {
857  friendlyName = this._deviceProperties.friendlyName;
858  this._lastPropertyValue.friendlyName = friendlyNname;
859  } catch(err) {
860  if (this._lastPropertyValue.friendlyName) {
861  friendlyName = this._lastPropertyValue.friendlyName;
862  }
863  }
864  if (friendlyName == null)
865  friendlyName = SBString("device.info.unknown");
866 
867  return friendlyName;
868  },
869 
870 
877  _getDeviceSerialNumber: function DIW__getDeviceSerialNumber() {
878  var serialNumber = null;
879  try {
880  serialNumber = this._deviceProperties.serialNumber;
881  this._lastPropertyValue.serialNumber = serialNumber;
882  } catch(err) {
883  if (this._lastPropertyValue.serialNumber) {
884  serialNumber = this._lastPropertyValue.serialNumber;
885  }
886  }
887  if (serialNumber == null)
888  serialNumber = SBString("device.info.unknown");
889 
890  return serialNumber;
891  },
892 
893 
900  _getDeviceVendor: function DIW__getDeviceVendor() {
901  var vendorName = null;
902  try {
903  vendorName = this._deviceProperties.vendorName;
904  this._lastPropertyValue.vendorName = this._lastPropertyValue.vendorName;
905  } catch(err) {
906  if (this._lastPropertyValue.vendorName) {
907  vendorName = this._lastPropertyValue.vendorName;
908  }
909  }
910  if (vendorName == null)
911  vendorName = SBString("device.info.unknown");
912 
913  return vendorName;
914  },
915 
916  _getDeviceFirmwareVersion: function DIW__getDeviceFirmwareVersion() {
917  var firmwareVersion = null;
918 
919  var deviceFirmwareUpdater =
920  Cc["@songbirdnest.com/Songbird/Device/Firmware/Updater;1"]
921  .getService(Ci.sbIDeviceFirmwareUpdater);
922 
923  // If we have a firmware handler for the device, use it to read
924  // the device firmware version. Don't use the device properties firmware
925  // version as it will generally not match the version displayed in the
926  // device UI.
927  if(deviceFirmwareUpdater.hasHandler(this._device, 0, 0)) {
928  var handler = deviceFirmwareUpdater.getHandler(this._device, 0, 0);
929  handler.bind(this._device, null);
930 
931  try {
932  firmwareVersion = handler.currentFirmwareReadableVersion;
933  }
934  catch(err) {}
935 
936  handler.unbind();
937 
938  if (firmwareVersion == null) {
939  firmwareVersion = SBString("device.info.unknown");
940  }
941  }
942  else {
943  firmwareVersion = "";
944  }
945 
946  return firmwareVersion;
947  },
948 
955  _getDeviceAccessCompatibility: function DIW__getDeviceAccessCompatibility() {
956  var accessCompatibility =
957  this._getDeviceProperty
958  ("http://songbirdnest.com/device/1.0#accessCompatibility",
959  SBString("device.info.unknown"));
960  return accessCompatibility;
961  },
962 
969  _getDeviceAccessCompatibilityDesc: function DIW__getDeviceAccessCompatibilityDesc() {
970  var accessCompatibility = this._getDeviceAccessCompatibility();
971  if (accessCompatibility == "ro")
972  accessCompatibility = SBString("device.info.read_only");
973  else if (accessCompatibility == "rw")
974  accessCompatibility = SBString("device.info.read_write");
975 
976  return accessCompatibility;
977  },
978 
985  _getExtsForMimeType : function(aMimeType, aContentType) {
986  var exts = [];
987  var idx = 0;
988 
989  // Use the device capabilities utils mapping
990  var devCapsUtils =
991  Cc["@songbirdnest.com/Songbird/Device/DeviceCapabilitiesUtils;1"]
992  .getService(Ci.sbIDeviceCapabilitiesUtils);
993  var extEnum = devCapsUtils.mapContentTypeToFileExtensions(aMimeType,
994  aContentType);
995  while (extEnum.hasMore()) {
996  exts[idx++] = extEnum.getNext();
997  }
998 
999  if (exts.length > 0)
1000  return exts;
1001 
1002  // As a fallback, use nsIMIMEService to look it up
1003  var mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
1004  if (mimeService) {
1005  var mimeExtension;
1006  try {
1007  mimeExtension = mimeService.getFromTypeAndExtension(aMimeType, null)
1008  .primaryExtension;
1009  } catch (err) {}
1010 
1011  if (mimeExtension) {
1012  exts[idx] = SBString("device.info.mimetype." + mimeExtension, mimeExtension);
1013  return exts;
1014  }
1015  }
1016 
1017  // Fall back to mime type if all else failed.
1018  exts[idx] = aMimeType;
1019  return exts;
1020  },
1021 
1028  _getDevicePlaybackFormats: function DIW__getDevicePlaybackFormats() {
1029  var retFormats = [];
1030  var extensions = [];
1031  try {
1032  var deviceCapabilities = this._device.capabilities;
1033  var functionArray = deviceCapabilities.getSupportedFunctionTypes({});
1034  for (var functionCounter = 0;
1035  functionCounter < functionArray.length;
1036  functionCounter++)
1037  {
1038  var contentArray = deviceCapabilities.getSupportedContentTypes(
1039  functionArray[functionCounter], {});
1040  for (var contentCounter = 0;
1041  contentCounter < contentArray.length;
1042  contentCounter++)
1043  {
1044  var mimeTypeArray = deviceCapabilities.getSupportedMimeTypes(
1045  contentArray[contentCounter], {});
1046  if (mimeTypeArray.length > 0) {
1047  for each (var mimetype in mimeTypeArray) {
1048  var exts = this._getExtsForMimeType(mimetype,
1049  contentArray[contentCounter]);
1050  for (var idx = 0; idx < exts.length; idx++) {
1051  let ext = exts[idx];
1052  if (extensions.indexOf(ext) == -1)
1053  extensions.push(ext);
1054  }
1055  }
1056  }
1057  }
1058  }
1059  } catch (err) { }
1060 
1061  extensions.sort();
1062 
1063  return extensions.join(", ") || SBString("device.info.unknown");
1064  },
1065 
1075  _getDeviceBatteryStatus: function DIW__getDeviceBatteryStatus
1076  (aBatteryLevel,
1077  aOnBatteryPower) {
1078  aBatteryLevel.value = this._getDeviceProperty
1079  ("http://songbirdnest.com/device/1.0#batteryLevel",
1080  -1);
1081  var powerSource = this._getDeviceProperty
1082  ("http://songbirdnest.com/device/1.0#powerSource", 0);
1083  aOnBatteryPower.value = (parseInt(powerSource) ? true : false);
1084  },
1085 
1086 
1093  _supportsDeviceSpec: function DIW__supportsDeviceSpec(aDeviceSpec) {
1094  // Check if device supports device spec.
1095  switch (aDeviceSpec) {
1096  case "model" :
1097  case "capacity" :
1098  case "model_capacity" :
1099  case "product_capacity" :
1100  case "friendly_name" :
1101  case "serial_number" :
1102  case "vendor" :
1103  case "access" :
1104  case "playback_formats" :
1105  case "battery" :
1106  case "firmware_version" :
1107  return true;
1108 
1109  default :
1110  break;
1111  }
1112 
1113  return false;
1114  },
1115 
1116 
1123  _getDeviceIcon: function DIW__getDeviceIcon() {
1124  try {
1125  var uri = this._deviceProperties.iconUri;
1126  this._lastPropertyValue.uri = uri;
1127  var spec = uri.spec;
1128  if (uri.schemeIs("file") && /\.ico$/(spec)) {
1129  // try to use a suitably sized image
1130  spec = "moz-icon://" + spec + "?size=64";
1131  }
1132  return spec;
1133  } catch (err) {
1134  if (this._lastPropertyValue.uri) {
1135  return this._lastPropertyValue.uri;
1136  }
1137  // default image dictated by CSS.
1138  return null;
1139  }
1140  }
1141 };
1142 
1143 
const Cu
function Fx prototype initialize
const Cc
const XUL_NS
Definition: FeedWriter.js:83
function SBFormattedString(aKey, aParams, aDefault, aStringBundle)
onPageChanged aValue
Definition: FeedWriter.js:1395
function SBString(aKey, aDefault, aStringBundle)
Definition: StringUtils.jsm:93
var DIW
Definition: deviceInfo.js:78
var _this
return null
Definition: FeedWriter.js:1143
var uri
Definition: FeedWriter.js:1135
countRef value
Definition: FeedWriter.js:1423
const Cr
const Ci
_getSelectedPageStyle s i
GstMessage gpointer data sbGStreamerMessageHandler * handler