deviceInfoPanel.js
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2010 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
30 //------------------------------------------------------------------------------
31 //------------------------------------------------------------------------------
32 //
33 // Device info panel widget.
34 //
35 //------------------------------------------------------------------------------
36 //------------------------------------------------------------------------------
37 
38 //------------------------------------------------------------------------------
39 //
40 // Device info panel defs.
41 //
42 //------------------------------------------------------------------------------
43 
44 // Component manager defs.
45 if (typeof(Cc) == "undefined")
46  var Cc = Components.classes;
47 if (typeof(Ci) == "undefined")
48  var Ci = Components.interfaces;
49 if (typeof(Cr) == "undefined")
50  var Cr = Components.results;
51 if (typeof(Cu) == "undefined")
52  var Cu = Components.utils;
53 
54 Cu.import("resource://app/jsmodules/sbProperties.jsm");
55 Cu.import("resource://app/jsmodules/WindowUtils.jsm");
56 
57 var TYPE = { "NONE": 0,
58  "MUSIC": 1,
59  "VIDEO": 2,
60  "IMAGE": 4 };
61 
62 //------------------------------------------------------------------------------
63 //
64 // Device info panel service.
65 //
66 //------------------------------------------------------------------------------
67 
68 var DIPW = {
69  //
70  // Device info panel object fields.
71  // MEDIA_TYPES_IN_TAB_DISPLAY_ORDER An array of media type strings in tab
72  // display order
73  // _widget Device info widget.
74  // _deviceID Device ID.
75  // _panelBar The information panel bar widget to use.
76  // _lastOperation The last operation performed on this device.
77  // _lastDirection The direction of the last operation performed on
78  // on this device
79  // _itemType The processing item type
80  // _removePanels The flag to remove all the panels before setup
81 
82  MEDIA_TYPES_IN_TAB_DISPLAY_ORDER: ["audio", "video", "image", "none"],
83  _widget: null,
84  _deviceID: null,
85  _panelBar: null,
86  _lastOperation: null,
87  _lastDirection: null,
88  _deviceErrorMonitor : null,
89  _itemType: null,
90  _removePanels: false,
91  _lastUpdateTimeout: null,
92  _operationDR : null,
93  _debug : Application.prefs.getValue("songbird.device.errorInfoPanel.debug",
94  false),
95  _log : function DIPW__log(aMsg) {
96  if (this._debug) {
97  dump("deviceInfoPanel-" + aMsg + "\n");
98  }
99  },
107  initialize: function DIPW__initialize(aWidget) {
108  this._log("initialize");
109  // Get the device widget.
110  this._widget = aWidget;
111 
112  // Get some widget elements.
113  this._panelBar = this._getElement("device_info_panel_bar");
114 
115  // Listen to the click/keypress events for OK button in the progress widget
116  document.addEventListener("sbDeviceProgress-ok-button-enter",
117  this,
118  false);
119 
120  // Initialize object fields.
121  this._deviceID = this._widget.deviceID;
122  this._device = this._widget.device;
123 
124  // Always want to remove all the panels before syncing starts
125  this._removePanels = true;
126 
127  // Initialize the device services.
128  this._deviceInitialize();
129 
130  // Grab the device error monitor service so we can check for errors on this
131  // device when we need to.
132  this._deviceErrorMonitor =
133  Cc["@songbirdnest.com/device/error-monitor-service;1"]
134  .getService(Ci.sbIDeviceErrorMonitor);
135 
136  // Get the processing item type
137  var createDataRemote = new Components.Constructor(
138  "@songbirdnest.com/Songbird/DataRemote;1",
139  Ci.sbIDataRemote,
140  "init");
141 
142  this._itemType = createDataRemote(this._deviceID + ".status.type", null);
143 
144  this._operationDR = createDataRemote(this._deviceID + ".status.operation",
145  null);
146  this._update();
147 
148  },
149 
154  finalize: function DIPW_finalize() {
155  this._log("finalize");
156  // Clean up the device error monitor
157  if (this._deviceErrorMonitor) {
158  this._deviceErrorMonitor = null;
159  }
160  // Finalize the device services.
161  this._deviceFinalize();
162 
163  // Clear object fields.
164  this._widget = null;
165  this._deviceID = null;
166  this._panelBar = null;
167  this._itemType = null;
168  this._operationDR = null;
169  },
170 
171  //----------------------------------------------------------------------------
172  //
173  // Device info panel UI update services.
174  //
175  //----------------------------------------------------------------------------
176 
177 
184  _getCopyingState: function DIPW__getCopyingState() {
185  if (this._itemType.intValue & TYPE.MUSIC)
186  return Ci.sbIDevice.STATE_COPYING_MUSIC;
187  else if (this._itemType.intValue & TYPE.VIDEO)
188  return Ci.sbIDevice.STATE_COPYING_VIDEO;
189  else if (this._itemType.intValue & TYPE.IMAGE)
190  return Ci.sbIDevice.STATE_COPYING_IMAGE;
191  else
192  return Ci.sbIDevice.STATE_IDLE;
193  },
194 
204  _getDeviceState: function DIPW__getDeviceState() {
205  // Get the current device state.
206  var deviceState = this._device.state;
207  var substate = this._device.currentStatus.currentSubState;
208  var state = deviceState;
209  if (deviceState == Ci.sbIDevice.STATE_SYNCING) {
210  if (substate == Ci.sbIDevice.STATE_SYNCING_TYPE ||
211  substate == Ci.sbIDevice.STATE_COPY_PREPARING ||
212  substate == Ci.sbIDevice.STATE_SYNC_PLAYLIST ||
213  substate == Ci.sbIDevice.STATE_UPDATING ||
214  substate == Ci.sbIDevice.STATE_IDLE) {
215  state = substate;
216  }
217  else if (substate == Ci.sbIDevice.STATE_COPYING ||
218  substate == Ci.sbIDevice.STATE_DELETING ||
219  substate == Ci.sbIDevice.STATE_TRANSCODE) {
220  state = this._getCopyingState();
221  }
222  }
223  else if (deviceState == Ci.sbIDevice.STATE_TRANSCODE) {
224  state = this._getCopyingState();
225  }
226  // Handle the case when dragging items to the main library while device
227  // is in syncing mode
228  else if (deviceState == Ci.sbIDevice.STATE_COPYING &&
229  substate == Ci.sbIDevice.STATE_IDLE) {
230  if (this._itemType.intValue == TYPE.NONE) {
231  state = Ci.sbIDevice.STATE_COPYING;
232  }
233  else {
234  state = this._getCopyingState();
235  }
236  }
237 
238  return state;
239  },
240 
244  _supportsVideo: function DIPW__supportsVideo() {
245  var capabilities = this._device.capabilities;
246  var sbIDC = Ci.sbIDeviceCapabilities;
247  try {
248  if (capabilities.supportsContent(sbIDC.FUNCTION_VIDEO_PLAYBACK,
249  sbIDC.CONTENT_VIDEO)) {
250  return true;
251  }
252  } catch (e) {}
253 
254  // couldn't find VIDEO support
255  return false;
256  },
257 
263  _updateOperation: function DIPW__updateOperation(aMediaType, aState, aDirection) {
264  if (this._lastOperation != aState ||
265  this._lastDirection != aDirection) {
266  this._updateMediaInfoPanelState(aMediaType,
267  aDirection,
268  Ci.sbIDevice.STATE_SYNCING,
269  true);
270 
271  // Update the current panel
272  let panel = this._findMediaInfoPanel(aMediaType);
273  if (panel && panel.index != 0) {
274  this._removeMediaInfoPanelsAfter(aMediaType, aDirection);
275  this._updateMediaInfoPanelState(aMediaType,
276  aDirection,
277  Ci.sbIDevice.STATE_SYNCING,
278  true);
279  }
280 
281  // Update the preceding panels to a complete state
282  for each (let type in this.MEDIA_TYPES_IN_TAB_DISPLAY_ORDER) {
283 
284  // Don't worry about the current mediaType
285  if (aMediaType == type) {
286  break;
287  }
288 
289  // If we find a different mediaType's panel, set it to complete with
290  // STATE_IDLE. It should handle error reporting if necessary.
291  if (this._findMediaInfoPanel(type)) {
292  this._updateMediaInfoPanelState(type,
293  -1,
294  Ci.sbIDevice.STATE_IDLE,
295  false);
296  }
297  }
298  this._lastOperation = aState;
299  this._lastDirection = aDirection;
300  // Make sure we are visible since the state has changed
301  if (!this._panelBar.isShown)
302  this._panelBar.animateIn();
303  }
304  },
305 
322  _update: function DIPW__update() {
323  this._log("deviceInfoPanel._update");
324  var deviceType = this._device.parameters.getProperty("DeviceType");
325  var state = Ci.sbIDevice.STATE_IDLE;
326  if ((deviceType == "WPD") ||
327  (deviceType == "MTP") ||
328  (deviceType == "MSCUSB")) {
329  state = this._getDeviceState();
330  }
331  if (state != Ci.sbIDevice.STATE_IDLE &&
332  this._lastUpdateTimeout) {
333  clearTimeout(this._lastUpdateTimeout);
334  this._lastUpdateTimeout = null;
335  }
336  // See if we're importing or exporting. "Reading" is the only import
337  // operation
338  var direction = this._operationDR.stringValue == "reading" ?
339  Ci.sbIDeviceStatus.IMPORT : Ci.sbIDeviceStatus.EXPORT;
340  this._log("state=" + state +
341  ", lastOperation=" + this._lastOperation +
342  ", direction=" + direction);
343  switch (state) {
344  case Ci.sbIDevice.STATE_COPYING:
345  case Ci.sbIDevice.STATE_COPY_PREPARING:
346  case Ci.sbIDevice.STATE_SYNCING_TYPE:
347  break;
348 
349  case Ci.sbIDevice.STATE_SYNC_PREPARING:
350  // Need to clear things up if users did not click OK button.
351  this._panelBar.removeAllPanels();
352  if (this._panelBar.isShown)
353  this._panelBar.animateOut();
354  this._lastOperation = state;
355  this._lastDirection = direction;
356  break;
357 
358  case Ci.sbIDevice.STATE_IMAGESYNC_PREPARING:
359  this._lastOperation = state;
360  this._lastDirection = direction;
361  break;
362 
363  case Ci.sbIDevice.STATE_UPDATING:
364  case Ci.sbIDevice.STATE_DELETING:
365  var active = state == Ci.sbIDevice.STATE_UPDATING ||
366  state == Ci.sbIDevice.STATE_DELETING;
367  // If we are syncing set up the panels for the types we are going to
368  // sync.
369 
370  // Clear any previous errors we have.
371  this._deviceErrorMonitor.clearErrorsForDevice(this._device);
372 
373  // When dragging items to the library and syncing starts, no state
374  // SYNC_PREPARING in between. Remove all panels.
375  if (this._removePanels) {
376  this._panelBar.removeAllPanels();
377  this._removePanels = false;
378  }
379 
380  // Make sure we are visible
381  if (this._itemType.intValue &&
382  !this._panelBar.isShown)
383  this._panelBar.animateIn();
384 
385  var completeAudio, completeVideo;
386  // Set up the panels for the upcoming syncing.
387  if ((this._itemType.intValue & TYPE.MUSIC) &&
388  !this._findMediaInfoPanel("audio")) {
389  this._updateMediaInfoPanel("audio",
390  Ci.sbIDeviceStatus.EXPORT,
391  SBString("device.infoPanel.audio_sync"),
392  "sync",
393  active);
394  if (active) {
395  this._updateMediaInfoPanelState("audio",
396  Ci.sbIDeviceStatus.EXPORT,
397  Ci.sbIDevice.STATE_SYNCING,
398  true);
399  }
400  }
401 
402  if ((this._itemType.intValue & TYPE.VIDEO) &&
403  this._supportsVideo() &&
404  !this._findMediaInfoPanel("video")) {
405  this._updateMediaInfoPanel("video",
406  Ci.sbIDeviceStatus.EXPORT,
407  SBString("device.infoPanel.video_sync"),
408  "sync",
409  active);
410  if (active) {
411  this._updateMediaInfoPanelState("video",
412  Ci.sbIDeviceStatus.EXPORT,
413  Ci.sbIDevice.STATE_SYNCING,
414  true);
415  }
416  completeAudio = true;
417  }
418  if ((this._itemType.intValue & TYPE.IMAGE) &&
419  !this._findMediaInfoPanel("image")) {
420  this._updateMediaInfoPanel("image",
421  Ci.sbIDeviceStatus.EXPORT,
422  SBString("device.infoPanel.image_sync"),
423  "sync",
424  active);
425  if (active) {
426  this._updateMediaInfoPanelState("image",
427  Ci.sbIDeviceStatus.EXPORT,
428  Ci.sbIDevice.STATE_SYNCING,
429  true);
430  }
431  completeAudio = true;
432  completeVideo = true;
433  }
434 
435  if (completeAudio) {
436  if (this._findMediaInfoPanel("audio")) {
437  this._updateMediaInfoPanelState("audio",
438  Ci.sbIDeviceStatus.EXPORT,
439  Ci.sbIDevice.STATE_IDLE,
440  false);
441  }
442  }
443  if (completeVideo) {
444  if (this._findMediaInfoPanel("audio")) {
445  this._updateMediaInfoPanelState("audio",
446  Ci.sbIDeviceStatus.EXPORT,
447  Ci.sbIDevice.STATE_IDLE,
448  false);
449  }
450  }
451 
452  // - Set last operation when itemType is 0 (!= audio|video|image). This
453  // is necessary for cases that IDLE follows SYNCING_TYPE.
454  // If _itemType == 0, the sync will complete for the following IDLE.
455  if (!this._itemType.intValue) {
456  this._lastOperation = state;
457  this._lastDirection = direction;
458  }
459  break;
460 
461  case Ci.sbIDevice.STATE_COPYING_MUSIC:
462  this._updateOperation("audio", state, direction);
463  break;
464 
465  case Ci.sbIDevice.STATE_COPYING_VIDEO:
466  this._updateOperation("video", state, direction);
467  break;
468 
469  case Ci.sbIDevice.STATE_SYNC_PLAYLIST:
470  // Syncing playlist.
471  this._lastOperation = state;
472  this._lastDirection = direction;
473  break;
474 
475  case Ci.sbIDevice.STATE_COPYING_IMAGE:
476  this._updateOperation("image", state, direction);
477  break;
478 
479  case Ci.sbIDevice.STATE_IDLE:
480  // For MTP, if IDLE after a SYNC_PLAYLIST then it is ok to disconnect.
481  // For MSC, IDLE after COPYING_MUSIC/COPYING_VIDEO is also applicable.
482  // Sync empty playlists can leave the last operation to COPY_PREPARING,
483  // SYNCING_TYPE and UPDATING. Remove playlists with only one item can
484  // give out DELETING.
485  switch (this._lastOperation) {
486  case Ci.sbIDevice.STATE_SYNC_PLAYLIST:
487  case Ci.sbIDevice.STATE_IMAGESYNC_PREPARING:
488  case Ci.sbIDevice.STATE_COPYING_IMAGE:
489  case Ci.sbIDevice.STATE_COPYING_MUSIC:
490  case Ci.sbIDevice.STATE_COPYING_VIDEO:
491  case Ci.sbIDevice.STATE_SYNCING_TYPE:
492  case Ci.sbIDevice.STATE_COPY_PREPARING:
493  case Ci.sbIDevice.STATE_UPDATING:
494  case Ci.sbIDevice.STATE_DELETING:
495  break;
496  default:
497  for each (let type in ["audio", "video", "image", "none"]) {
498  if (this._checkForDeviceErrors(type, Ci.sbIDeviceStatus.EXPORT)) {
499  this._log("Export errors for " + type);
500  this._updateMediaInfoPanelState(type,
501  Ci.sbIDeviceStatus.EXPORT,
502  state,
503  false);
504  // Make sure we are visible
505  if (!this._panelBar.isShown)
506  this._panelBar.animateIn();
507  }
508  if (this._checkForDeviceErrors(type, Ci.sbIDeviceStatus.IMPORT)) {
509  this._log("Import errors for " + type);
510  this._updateMediaInfoPanelState(type,
511  Ci.sbIDeviceStatus.IMPORT,
512  state,
513  false);
514  // Make sure we are visible
515  if (!this._panelBar.isShown)
516  this._panelBar.animateIn();
517  }
518  if (this._checkForDeviceErrors(type, 0)) {
519  this._log("Other errors for " + type);
520  this._updateMediaInfoPanelState(type,
521  0,
522  state,
523  false);
524  // Make sure we are visible
525  if (!this._panelBar.isShown)
526  this._panelBar.animateIn();
527  }
528  }
529  return;
530  }
531  // Intentional fall through, to process common idle/cancel logic
532  case Ci.sbIDevice.STATE_CANCEL:
533 
534  if (this._lastUpdateTimeout)
535  break;
536 
537  var _onLastUpdate = function(self) {
538 
539  // For MSC device. Finish up video panel if opened.
540  // audio panel has to be finished up for CANCEL.
541  if (self._findMediaInfoPanel("video")) {
542  self._updateMediaInfoPanelState("video",
543  self._lastDirection,
544  Ci.sbIDevice.STATE_IDLE,
545  false);
546  }
547  if (self._findMediaInfoPanel("audio")) {
548  self._updateMediaInfoPanelState("audio",
549  self._lastDirection,
550  Ci.sbIDevice.STATE_IDLE,
551  false);
552  }
553  if (self._findMediaInfoPanel("image")) {
554  self._updateMediaInfoPanelState("image",
555  0,
556  Ci.sbIDevice.STATE_IDLE,
557  false);
558  }
559 
560  // Update the existing one to OK to disconnect
561  self._updateMediaInfoPanel("complete",
562  direction,
563  SBString("device.status.progress_complete"),
564  "success",
565  true);
566 
567  // Reset to remove all panel for next sync.
568  self._removePanels = true;
569 
570  self._lastOperation = state;
571  }
572 
573  this._lastUpdateTimeout = setTimeout(_onLastUpdate, 1000, this);
574 
575  break;
576 
577  default:
578  this._lastOperation = null;
579  this._lastDirection = null;
580  if (this._panelBar.isShown)
581  this._panelBar.animateOut();
582  break;
583  }
584  },
585 
594  _removeMediaInfoPanel: function DIPW__removeMediaInfoPanel(aMediaType,
595  aDirection) {
596  var mediaPanel;
597  while ((mediaPanel = this._findMediaInfoPanel(aMediaType)) != null) {
598  var index = mediaPanel.index;
599  this._panelBar.removePanelAt(index);
600  }
601  },
602 
609  _removeMediaInfoPanelsAfter: function DIPW__removeMediaInfoPanelAfter(
610  aMediaType,
611  aDirection) {
612  let panelCount = this._panelBar.panelCount;
613  for (var index = 0; index < panelCount; index++) {
614  var aPanel = this._panelBar.getPanelAtIndex(index);
615  if (aPanel &&
616  aPanel.getAttribute("mediatype") == aMediaType &&
617  aPanel.getAttribute("direction") == aDirection) {
618  while (++index < panelCount) {
619  this._panelBar.removePanelAt(index);
620  }
621  return;
622  }
623  }
624  },
635  _updateMediaInfoPanelState: function DIPW__updateMediaInfoPanelState(
636  aMediaType,
637  aDirection,
638  aState,
639  aIsActive) {
640  this._log("_updateMediaInfoPanelState(" + aMediaType +
641  ", " + aDirection +
642  ", " + aState +
643  ", " + aIsActive + ")");
644  // Anything but import is considered "sync"
645  var direction = "sync";
646  if (aDirection == Ci.sbIDeviceStatus.IMPORT) {
647  direction = "import";
648  }
649  var baseString = "device.infoPanel." + aMediaType;
650  var hasErrors = false;
651  switch (aState) {
652  case Ci.sbIDevice.STATE_IDLE:
653  hasErrors = this._checkForDeviceErrors(aMediaType);
654  this._log("hasErrors=" + hasErrors);
655  if (hasErrors) {
656  var mediaPanel = this._updateMediaInfoPanel(
657  aMediaType,
658  aDirection,
659  SBString(baseString + "_errors"),
660  "error",
661  aIsActive);
662  mediaPanel.addEventListener("sbInfoPanel-icon-click",
663  this,
664  false);
665  mediaPanel.setAttribute("icon-clickable", true);
666  }
667  else {
668  var mediaPanel = this._updateMediaInfoPanel(
669  aMediaType,
670  aDirection,
671  SBString(baseString + "_complete"),
672  "success",
673  aIsActive);
674  }
675  break;
676 
677  case Ci.sbIDevice.STATE_SYNCING:
678  var mediaPanel = this._updateMediaInfoPanel(
679  aMediaType,
680  aDirection,
681  SBString(baseString + "_" + direction + "_progress"),
682  "sync",
683  aIsActive);
684  break;
685  }
686 
687  return hasErrors;
688  },
689 
700  _updateMediaInfoPanel: function DIPW__updateMediaInfoPanel(aMediaType,
701  aDirection,
702  aMediaLabel,
703  aSyncState,
704  aIsActive) {
705  this._log("_updateMediaInfoPanel(" + aMediaType + ", " +
706  aDirection + ", " +
707  aMediaLabel + ", " +
708  aSyncState + ", " +
709  aIsActive + ")");
710  var mediaPanel = this._findMediaInfoPanel(aMediaType);
711  if (mediaPanel == null) {
712  this._log("New panel");
713  mediaPanel = this._panelBar.appendPanel(aMediaLabel, "", aIsActive);
714  mediaPanel.setAttribute("mediatype", aMediaType);
715  mediaPanel.setAttribute("direction", aDirection);
716  }
717  else {
718  this._log("Existing panel: " + mediaPanel.label);
719  mediaPanel.label = aMediaLabel;
720  mediaPanel.active = aIsActive;
721  }
722 
723  if (aSyncState)
724  mediaPanel.setAttribute("state", aSyncState);
725  else
726  mediaPanel.removeAttribute("state");
727 
728  // Remove icon-clickable by default.
729  mediaPanel.removeAttribute("icon-clickable");
730  return mediaPanel;
731  },
732 
740  _findMediaInfoPanel: function DIPW__findMediaInfoPanel(aMediaType) {
741  var panelCount = this._panelBar.panelCount;
742  for (var index = 0; index < panelCount; index++) {
743  var aPanel = this._panelBar.getPanelAtIndex(index);
744  if (aPanel &&
745  aPanel.getAttribute("mediatype") == aMediaType)
746  return aPanel;
747  }
748  return null;
749  },
750 
758  handleEvent: function DIPW_handleEvent(aEvent) {
759  // Check if this is a panel icon click event.
760  if (aEvent.type == "sbInfoPanel-icon-click") {
761  var target = aEvent.target
762  // Make sure our target has a media type
763  if (target.hasAttribute("mediatype")) {
764  let mediaType = target.getAttribute("mediatype");
765  let direction = target.getAttribute("direction");
766  this._log("handleEvent: mediaType=" + mediaType + ", directionType=" + direction);
767  if (this._checkForDeviceErrors(mediaType, direction)) {
768  var errorItems =
769  this._deviceErrorMonitor.getDeviceErrors(this._device,
770  mediaType,
771  direction);
772  WindowUtils.openDialog
773  (window,
774  "chrome://songbird/content/xul/device/deviceErrorDialog.xul",
775  "device_error_dialog",
776  "chrome,centerscreen",
777  false,
778  [ "", this._device, errorItems, direction != Ci.sbIDeviceStatus.IMPORT ? "syncing" : "importing"],
779  null);
780 
781  // We handled this event so stop the propagation
782  aEvent.stopPropagation();
783  aEvent.preventDefault();
784  }
785  }
786  }
787  else if (aEvent.type == "sbDeviceProgress-ok-button-enter") {
788  this._panelBar.removeAllPanels();
789  if (this._panelBar.isShown)
790  this._panelBar.animateOut();
791  }
792  },
793 
794  //----------------------------------------------------------------------------
795  //
796  // Device info panel XUL services.
797  //
798  //----------------------------------------------------------------------------
799 
809  _getElement: function DIPW__getElement(aElementID) {
810  return document.getAnonymousElementByAttribute(this._widget,
811  "sbid",
812  aElementID);
813  },
814 
815  //----------------------------------------------------------------------------
816  //
817  // Device info panel device services.
818  //
819  // These services provide an interface to the device object.
820  // These services register for any pertinent device notifications and call
821  // _update to update the UI accordingly. In particular, these services
822  // register to receive notifications when the device state changes.
823  //
824  //----------------------------------------------------------------------------
825 
826  //
827  // Device info services fields.
828  //
829  // _device sbIDevice object.
830  //
831 
832  _device: null,
833 
834 
839  _deviceInitialize: function DIPW__deviceInitialize() {
840  // Add a listener for status operations
841  if (this._device) {
842  var deviceEventTarget = this._device;
843  deviceEventTarget.QueryInterface(Ci.sbIDeviceEventTarget);
844  deviceEventTarget.addEventListener(this);
845  }
846  },
847 
852  _deviceFinalize: function DIPW__deviceFinalize() {
853  // Clear object fields.
854  if (this._device) {
855  var deviceEventTarget = this._device;
856  deviceEventTarget.QueryInterface(Ci.sbIDeviceEventTarget);
857  deviceEventTarget.removeEventListener(this);
858  }
859  this._device = null;
860  },
861 
866  _checkForDeviceErrors: function DIPW__checkForDeviceErrors(aMediaType,
867  aDirection) {
868  if (aDirection) {
869  let hasErrors = false;
870  try {
871  hasErrors = this._deviceErrorMonitor.deviceHasErrors(this._device,
872  aMediaType,
873  aDirection);
874  } catch (err) {
875  Cu.reportError(err);
876  }
877  return hasErrors;
878  }
879  else {
880  let hasImportErrors = false;
881  let hasExportErrors = false;
882  try {
883  hasImportErrors = this._deviceErrorMonitor.deviceHasErrors
884  (this._device,
885  aMediaType,
886  Ci.sbIDeviceStatus.IMPORT);
887  hasExportErrors = this._deviceErrorMonitor.deviceHasErrors
888  (this._device,
889  aMediaType,
890  Ci.sbIDeviceStatus.EXPORT);
891  } catch (err) {
892  Cu.reportError(err);
893  }
894  return (hasImportErrors || hasExportErrors);
895  }
896  },
897 
904  onDeviceEvent : function DIPW_onDeviceEvent(aEvent) {
905  switch (aEvent.type) {
906  case Ci.sbIDeviceEvent.EVENT_DEVICE_STATE_CHANGED:
907  case Ci.sbIDeviceEvent.EVENT_DEVICE_MEDIA_WRITE_START:
908  case Ci.sbIDeviceEvent.EVENT_DEVICE_TRANSFER_START:
909  this._update();
910  break;
911  }
912  }
913 
914 };
const Cu
function Fx prototype initialize
var DIPW
const Cc
var Application
Definition: sbAboutDRM.js:37
var TYPE
function SBString(aKey, aDefault, aStringBundle)
Definition: StringUtils.jsm:93
let window
aWindow setTimeout(function(){_this.restoreHistory(aWindow, aTabs, aTabData, aIdMap);}, 0)
var createDataRemote
return null
Definition: FeedWriter.js:1143
function _log(aMsg, aMenuID)
const Cr
const Ci
restoreWindow aState