sbMockDevice.cpp
Go to the documentation of this file.
1 /* vim: set sw=2 :miv */
2 /*
3  *=BEGIN SONGBIRD GPL
4  *
5  * This file is part of the Songbird web player.
6  *
7  * Copyright(c) 2005-2011 POTI, Inc.
8  * http://www.songbirdnest.com
9  *
10  * This file may be licensed under the terms of of the
11  * GNU General Public License Version 2 (the ``GPL'').
12  *
13  * Software distributed under the License is distributed
14  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
15  * express or implied. See the GPL for the specific language
16  * governing rights and limitations.
17  *
18  * You should have received a copy of the GPL along with this
19  * program. If not, go to http://www.gnu.org/licenses/gpl.html
20  * or write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  *=END SONGBIRD GPL
24  */
25 
26 #include "sbMockDevice.h"
27 
28 #include <nsIPrefBranch.h>
29 #include <nsIPrefService.h>
30 #include <nsIVariant.h>
31 #include <nsIWritablePropertyBag.h>
32 #include <nsIWritablePropertyBag2.h>
33 
34 #include <nsArrayUtils.h>
35 #include <nsCOMPtr.h>
36 #include <nsComponentManagerUtils.h>
37 #include <nsServiceManagerUtils.h>
38 #include <nsXPCOMCIDInternal.h>
39 
40 #include <sbIDeviceCapabilities.h>
41 #include <sbIDeviceEvent.h>
42 #include <sbIDeviceLibrary.h>
43 #include <sbIDeviceManager.h>
44 #include <sbIDeviceProperties.h>
45 #include <sbRequestItem.h>
46 
47 #include <sbDeviceContent.h>
48 #include <sbVariantUtils.h>
49 
50 /* for an actual device, you would probably want to actually sort the prefs on
51  * the device itself (and not the mozilla prefs system). And even if you do end
52  * up wanting to store things in the prefs system for some odd reason, you would
53  * want to have a unique id per instance of the device and not a hard-coded one.
54  */
55 #define DEVICE_PREF_BRANCH \
56  "songbird.devices.mock.00000000-0000-0000-c000-000000000046."
57 
60 NS_INTERFACE_MAP_BEGIN(sbMockDevice)
61  NS_INTERFACE_MAP_ENTRY(sbIMockDevice)
62  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(sbIDevice, sbBaseDevice)
63  NS_INTERFACE_MAP_ENTRY(sbIDeviceEventTarget)
64  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, sbIDeviceEventTarget)
65 NS_INTERFACE_MAP_END
66 
67 #if _MSC_VER
68 // Disable warning about 'this' used in base member initializer list.
69 #pragma warning(disable: 4355)
70 #endif
71 
73  : mIsConnected(PR_FALSE)
74 {
75  Init();
76 }
77 
78 sbMockDevice::~sbMockDevice()
79 {
80  /* destructor code */
81 }
82 
83 /* readonly attribute AString name; */
84 NS_IMETHODIMP sbMockDevice::GetName(nsAString & aName)
85 {
86  aName.AssignLiteral("Bob's Mock Device");
87  return NS_OK;
88 }
89 
90 /* readonly attribute AString productName; */
91 NS_IMETHODIMP sbMockDevice::GetProductName(nsAString & aProductName)
92 {
93  aProductName.AssignLiteral("Mock Device");
94  return NS_OK;
95 }
96 
97 /* readonly attribute nsIDPtr controllerId; */
98 NS_IMETHODIMP sbMockDevice::GetControllerId(nsID * *aControllerId)
99 {
100  NS_ENSURE_ARG_POINTER(aControllerId);
101 
102  *aControllerId = (nsID*)NS_Alloc(sizeof(nsID));
103  NS_ENSURE_TRUE(*aControllerId, NS_ERROR_OUT_OF_MEMORY);
104  **aControllerId = NS_GET_IID(nsISupports);
105  return NS_OK;
106 }
107 
108 /* readonly attribute nsIDPtr id; */
109 NS_IMETHODIMP sbMockDevice::GetId(nsID * *aId)
110 {
111  NS_ENSURE_ARG_POINTER(aId);
112 
113  nsID mockDeviceID;
114 
115  PRBool success =
116  mockDeviceID.Parse("{3572E6FC-4954-4458-AFE7-0D0A65BF5F55}");
117  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
118 
119  *aId = (nsID*)NS_Alloc(sizeof(nsID));
120  NS_ENSURE_TRUE(*aId, NS_ERROR_OUT_OF_MEMORY);
121 
122  **aId = mockDeviceID;
123 
124  return NS_OK;
125 }
126 
127 /* void connect (); */
128 NS_IMETHODIMP sbMockDevice::Connect()
129 {
130  NS_ENSURE_STATE(!mIsConnected);
131  nsresult rv;
132 
133  // Invoke the super-class.
134  rv = sbBaseDevice::Connect();
135  NS_ENSURE_SUCCESS(rv, rv);
136 
137  nsCOMPtr<sbIDeviceContent> deviceContent;
138  rv = GetContent(getter_AddRefs(deviceContent));
139  NS_ENSURE_SUCCESS(rv, rv);
140 
141  // Start the request processing.
142  rv = ReqProcessingStart();
143  NS_ENSURE_SUCCESS(rv, rv);
144 
145  mIsConnected = PR_TRUE;
146  return NS_OK;
147 }
148 
149 NS_IMETHODIMP sbMockDevice::Disconnect()
150 {
151  mBatch.clear();
152  return sbBaseDevice::Disconnect();
153 }
154 
155 /* void disconnect (); */
156 nsresult sbMockDevice::DeviceSpecificDisconnect()
157 {
158  NS_ENSURE_STATE(mIsConnected);
159 
160  nsresult rv;
161  nsRefPtr<sbBaseDeviceVolume> volume;
162  {
163  nsAutoLock autoVolumeLock(mVolumeLock);
164  volume = mDefaultVolume;
165  mDefaultVolume = nsnull;
166  }
167  if (volume)
168  RemoveVolume(volume);
169 
170  mIsConnected = PR_FALSE;
171 
172  // Finalize the device content and device libraries
173  if (mContent) {
174  // Get a copy of the list of device libraries
175  nsCOMArray<sbIDeviceLibrary> libraryListCopy;
176  PRInt32 libraryListCopyCount;
177  nsCOMPtr<nsIArray> libraryList;
178  PRUint32 libraryCount;
179  rv = mContent->GetLibraries(getter_AddRefs(libraryList));
180  if (NS_SUCCEEDED(rv))
181  rv = libraryList->GetLength(&libraryCount);
182  if (NS_SUCCEEDED(rv)) {
183  for (PRUint32 i = 0; i < libraryCount; i++) {
184  nsCOMPtr<sbIDeviceLibrary>
185  library = do_QueryElementAt(libraryList, i, &rv);
186  if (NS_FAILED(rv))
187  continue;
188  libraryListCopy.AppendObject(library);
189  }
190  }
191  libraryListCopyCount = libraryListCopy.Count();
192 
193  // Finalize each device library
194  for (PRInt32 i = 0; i < libraryListCopyCount; i++) {
195  RemoveLibrary(libraryListCopy[i]);
196  FinalizeDeviceLibrary(libraryListCopy[i]);
197  }
198 
199  // Finalize the device content
200  mContent->Finalize();
201  mContent = nsnull;
202  }
203 
204  PRUint32 state = sbIDevice::STATE_IDLE;
205 
206  nsCOMPtr<sbIDeviceManager2> manager =
207  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
208  NS_ENSURE_SUCCESS(rv, rv);
209 
210  sbNewVariant data(static_cast<sbIDevice*>(static_cast<sbBaseDevice*>(this)));
211  nsCOMPtr<sbIDeviceEvent> deviceEvent;
212  rv = manager->CreateEvent(sbIDeviceEvent::EVENT_DEVICE_REMOVED,
213  sbNewVariant(static_cast<sbIDevice*>(static_cast<sbBaseDevice*>(this))),
214  data,
215  state,
216  state,
217  getter_AddRefs(deviceEvent));
218  NS_ENSURE_SUCCESS(rv, rv);
219 
220  PRBool dispatched;
221  rv = DispatchEvent(deviceEvent, PR_TRUE, &dispatched);
222  NS_ENSURE_SUCCESS(rv, rv);
223 
224  return NS_OK;
225 }
226 
227 /* readonly attribute boolean connected; */
228 NS_IMETHODIMP sbMockDevice::GetConnected(PRBool *aConnected)
229 {
230  NS_ENSURE_ARG_POINTER(aConnected);
231  *aConnected = mIsConnected;
232  return NS_OK;
233 }
234 
235 /* readonly attribute boolean threaded; */
236 NS_IMETHODIMP sbMockDevice::GetThreaded(PRBool *aThreaded)
237 {
238  NS_ENSURE_ARG_POINTER(aThreaded);
239  *aThreaded = PR_FALSE;
240  return NS_OK;
241 }
242 
243 /* nsIVariant getPreference (in AString aPrefName); */
244 NS_IMETHODIMP sbMockDevice::GetPreference(const nsAString & aPrefName, nsIVariant **_retval)
245 {
246  /* what, you expect a mock device to be actually useful? */
247  NS_ENSURE_ARG_POINTER(_retval);
248  nsresult rv;
249 
250  nsCOMPtr<nsIPrefService> prefRoot =
251  do_GetService("@mozilla.org/preferences-service;1", &rv);
252  NS_ENSURE_SUCCESS(rv, rv);
253 
254  nsCOMPtr<nsIPrefBranch> prefBranch;
255  rv = prefRoot->GetBranch(DEVICE_PREF_BRANCH, getter_AddRefs(prefBranch));
256  NS_ENSURE_SUCCESS(rv, rv);
257 
258  NS_LossyConvertUTF16toASCII prefNameC(aPrefName);
259 
260  PRInt32 prefType;
261  rv = prefBranch->GetPrefType(prefNameC.get(),
262  &prefType);
263  NS_ENSURE_SUCCESS(rv, rv);
264 
265  nsCOMPtr<nsIWritableVariant> result =
266  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
267  NS_ENSURE_SUCCESS(rv, rv);
268 
269  switch(prefType) {
270  case nsIPrefBranch::PREF_INVALID: {
271  rv = result->SetAsVoid();
272  NS_ENSURE_SUCCESS(rv, rv);
273  break;
274  }
275  case nsIPrefBranch::PREF_STRING: {
276  char *value = nsnull;
277  rv = prefBranch->GetCharPref(prefNameC.get(), &value);
278  NS_ENSURE_SUCCESS(rv, rv);
279  rv = result->SetAsString(value);
280  NS_Free(value);
281  NS_ENSURE_SUCCESS(rv, rv);
282  break;
283  }
284  case nsIPrefBranch::PREF_INT: {
285  PRInt32 value;
286  rv = prefBranch->GetIntPref(prefNameC.get(), &value);
287  NS_ENSURE_SUCCESS(rv, rv);
288  rv = result->SetAsInt32(value);
289  NS_ENSURE_SUCCESS(rv, rv);
290  break;
291  }
292  case nsIPrefBranch::PREF_BOOL: {
293  PRBool value;
294  rv = prefBranch->GetBoolPref(prefNameC.get(), &value);
295  NS_ENSURE_SUCCESS(rv, rv);
296  rv = result->SetAsBool(value);
297  NS_ENSURE_SUCCESS(rv, rv);
298  break;
299  }
300  default: {
301  /* wtf? */
302  return NS_ERROR_UNEXPECTED;
303  }
304  }
305 
306  return CallQueryInterface(result, _retval);
307 }
308 
309 /* void setPreference (in AString aPrefName, in nsIVariant aPrefValue); */
310 NS_IMETHODIMP sbMockDevice::SetPreference(const nsAString & aPrefName, nsIVariant *aPrefValue)
311 {
312  NS_ENSURE_ARG_POINTER(aPrefValue);
313  nsresult rv;
314 
315  nsCOMPtr<nsIPrefService> prefRoot =
316  do_GetService("@mozilla.org/preferences-service;1", &rv);
317  NS_ENSURE_SUCCESS(rv, rv);
318 
319  nsCOMPtr<nsIPrefBranch> prefBranch;
320  rv = prefRoot->GetBranch(DEVICE_PREF_BRANCH, getter_AddRefs(prefBranch));
321  NS_ENSURE_SUCCESS(rv, rv);
322 
323  NS_LossyConvertUTF16toASCII prefNameC(aPrefName);
324 
325  PRUint16 prefType;
326  rv = aPrefValue->GetDataType(&prefType);
327  NS_ENSURE_SUCCESS(rv, rv);
328 
329  PRInt32 oldPrefType;
330  rv = prefBranch->GetPrefType(prefNameC.get(), &oldPrefType);
331  NS_ENSURE_SUCCESS(rv, rv);
332 
333  switch(prefType) {
334  case nsIDataType::VTYPE_INT8:
335  case nsIDataType::VTYPE_INT16:
336  case nsIDataType::VTYPE_INT32:
337  case nsIDataType::VTYPE_INT64:
338  case nsIDataType::VTYPE_UINT8:
339  case nsIDataType::VTYPE_UINT16:
340  case nsIDataType::VTYPE_UINT32:
341  case nsIDataType::VTYPE_UINT64:
342  {
343  if (oldPrefType != nsIPrefBranch::PREF_INVALID &&
344  oldPrefType != nsIPrefBranch::PREF_INT) {
345  rv = prefBranch->ClearUserPref(prefNameC.get());
346  NS_ENSURE_SUCCESS(rv, rv);
347  }
348  PRInt32 value;
349  rv = aPrefValue->GetAsInt32(&value);
350  NS_ENSURE_SUCCESS(rv, rv);
351  rv = prefBranch->SetIntPref(prefNameC.get(), value);
352  NS_ENSURE_SUCCESS(rv, rv);
353 
354  /* special case for state */
355  if (aPrefName.Equals(NS_LITERAL_STRING("state"))) {
356  mState = value;
357  }
358 
359  break;
360  }
361  case nsIDataType::VTYPE_BOOL:
362  {
363  if (oldPrefType != nsIPrefBranch::PREF_INVALID &&
364  oldPrefType != nsIPrefBranch::PREF_BOOL) {
365  rv = prefBranch->ClearUserPref(prefNameC.get());
366  NS_ENSURE_SUCCESS(rv, rv);
367  }
368  PRBool value;
369  rv = aPrefValue->GetAsBool(&value);
370  NS_ENSURE_SUCCESS(rv, rv);
371  rv = prefBranch->SetBoolPref(prefNameC.get(), value);
372  NS_ENSURE_SUCCESS(rv, rv);
373  break;
374  }
375  default:
376  {
377  if (oldPrefType != nsIPrefBranch::PREF_INVALID &&
378  oldPrefType != nsIPrefBranch::PREF_STRING) {
379  rv = prefBranch->ClearUserPref(prefNameC.get());
380  NS_ENSURE_SUCCESS(rv, rv);
381  }
382  nsCString value;
383  rv = aPrefValue->GetAsACString(value);
384  NS_ENSURE_SUCCESS(rv, rv);
385  rv = prefBranch->SetCharPref(prefNameC.get(), value.get());
386  NS_ENSURE_SUCCESS(rv, rv);
387  break;
388  }
389  }
390 
391  return NS_OK;
392 }
393 
394 /* readonly attribute sbIDeviceCapabilities capabilities; */
395 NS_IMETHODIMP sbMockDevice::GetCapabilities(sbIDeviceCapabilities * *aCapabilities)
396 {
397  NS_ENSURE_ARG_POINTER(aCapabilities);
398  nsresult rv;
399 
400  // Create the device capabilities object.
401  nsCOMPtr<sbIDeviceCapabilities> caps =
402  do_CreateInstance(SONGBIRD_DEVICECAPABILITIES_CONTRACTID, &rv);
403  NS_ENSURE_SUCCESS(rv, rv);
404  rv = caps->Init();
405  NS_ENSURE_SUCCESS(rv, rv);
406 
407  PRUint32 functionTypes[] = {sbIDeviceCapabilities::FUNCTION_DEVICE,
409  rv = caps->SetFunctionTypes(functionTypes, NS_ARRAY_LENGTH(functionTypes));
410  NS_ENSURE_SUCCESS(rv, rv);
411 
412  PRUint32 contentTypes[] = {sbIDeviceCapabilities::CONTENT_VIDEO};
413  rv = caps->AddContentTypes(sbIDeviceCapabilities::FUNCTION_VIDEO_PLAYBACK,
414  contentTypes, NS_ARRAY_LENGTH(contentTypes));
415  NS_ENSURE_SUCCESS(rv, rv);
416 
417  const char* K_MIMETYPE_STRING = "ogg-theora-vorbis-sample-1";
418  rv = caps->AddMimeTypes(sbIDeviceCapabilities::CONTENT_VIDEO,
419  &K_MIMETYPE_STRING, 1);
420  NS_ENSURE_SUCCESS(rv, rv);
421 
422  nsCOMPtr<sbIDevCapVideoStream> videoFormat =
423  do_CreateInstance(SB_IDEVCAPVIDEOSTREAM_CONTRACTID, &rv);
424  NS_ENSURE_SUCCESS(rv, rv);
425 
426  nsCOMPtr<sbIImageSize> videoSize =
427  do_CreateInstance(SB_IMAGESIZE_CONTRACTID, &rv);
428  NS_ENSURE_SUCCESS(rv, rv);
429  rv = videoSize->Initialize(1280, 720);
430  NS_ENSURE_SUCCESS(rv, rv);
431  nsCOMPtr<nsIMutableArray> videoSizeArray =
432  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
433  NS_ENSURE_SUCCESS(rv, rv);
434  rv = videoSizeArray->AppendElement(videoSize, PR_FALSE);
435  NS_ENSURE_SUCCESS(rv, rv);
436 
437  nsCOMPtr<sbIDevCapRange> videoBitrateRange =
438  do_CreateInstance(SB_IDEVCAPRANGE_CONTRACTID, &rv);
439  NS_ENSURE_SUCCESS(rv, rv);
440  rv = videoBitrateRange->Initialize(100, 4 * 1024 * 1024, 100);
441  NS_ENSURE_SUCCESS(rv, rv);
442 
443  // Create the video par range:
444  nsCOMPtr<sbIDevCapFraction> parFraction =
445  do_CreateInstance("@songbirdnest.com/Songbird/Device/sbfraction;1", &rv);
446  NS_ENSURE_SUCCESS(rv, rv);
447  rv = parFraction->Initialize(1, 1);
448  NS_ENSURE_SUCCESS(rv, rv);
449  nsCOMPtr<nsIMutableArray> parFractionArray =
450  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
451  NS_ENSURE_SUCCESS(rv, rv);
452  rv = parFractionArray->AppendElement(parFraction, PR_FALSE);
453  NS_ENSURE_SUCCESS(rv, rv);
454 
455  // Create the video frame rate range:
456  nsCOMPtr<sbIDevCapFraction> frameRateFraction =
457  do_CreateInstance("@songbirdnest.com/Songbird/Device/sbfraction;1", &rv);
458  NS_ENSURE_SUCCESS(rv, rv);
459  rv = frameRateFraction->Initialize(30000, 1001);
460  NS_ENSURE_SUCCESS(rv, rv);
461  nsCOMPtr<nsIMutableArray> frameRateFractionArray =
462  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
463  NS_ENSURE_SUCCESS(rv, rv);
464  rv = frameRateFractionArray->AppendElement(frameRateFraction, PR_FALSE);
465  NS_ENSURE_SUCCESS(rv, rv);
466 
467  rv = videoFormat->Initialize(NS_LITERAL_CSTRING("video/x-theora"),
468  videoSizeArray,
469  nsnull, // explicit sizes only
470  nsnull, // explicit sizes only
471  parFractionArray,
472  PR_FALSE,
473  frameRateFractionArray,
474  PR_FALSE,
475  videoBitrateRange);
476 
477  nsCOMPtr<sbIDevCapAudioStream> audioFormat =
478  do_CreateInstance(SB_IDEVCAPAUDIOSTREAM_CONTRACTID, &rv);
479  NS_ENSURE_SUCCESS(rv, rv);
480  nsCOMPtr<sbIDevCapRange> audioBitrateRange =
481  do_CreateInstance(SB_IDEVCAPRANGE_CONTRACTID, &rv);
482  NS_ENSURE_SUCCESS(rv, rv);
483  rv = audioBitrateRange->Initialize(100, 4 * 1024 * 1024, 100);
484  NS_ENSURE_SUCCESS(rv, rv);
485  nsCOMPtr<sbIDevCapRange> audioSampleRateRange =
486  do_CreateInstance(SB_IDEVCAPRANGE_CONTRACTID, &rv);
487  NS_ENSURE_SUCCESS(rv, rv);
488  rv = audioSampleRateRange->Initialize(22050, 44100, 22050);
489  NS_ENSURE_SUCCESS(rv, rv);
490  nsCOMPtr<sbIDevCapRange> audioChannelsRange =
491  do_CreateInstance(SB_IDEVCAPRANGE_CONTRACTID, &rv);
492  NS_ENSURE_SUCCESS(rv, rv);
493  rv = audioChannelsRange->Initialize(1, 2, 1);
494  NS_ENSURE_SUCCESS(rv, rv);
495  rv = audioFormat->Initialize(NS_LITERAL_CSTRING("audio/x-vorbis"),
496  audioBitrateRange,
497  audioSampleRateRange,
498  audioChannelsRange);
499 
500  nsCOMPtr<sbIVideoFormatType> formatType =
501  do_CreateInstance(SB_IVIDEOFORMATTYPE_CONTRACTID, &rv);
502  NS_ENSURE_SUCCESS(rv, rv);
503  rv = formatType->Initialize(NS_LITERAL_CSTRING("application/ogg"),
504  videoFormat, audioFormat);
505  NS_ENSURE_SUCCESS(rv, rv);
506  rv = caps->AddFormatType(sbIDeviceCapabilities::CONTENT_VIDEO,
507  NS_ConvertASCIItoUTF16(K_MIMETYPE_STRING),
508  formatType);
509  NS_ENSURE_SUCCESS(rv, rv);
510 
511  // Complete the device capabilities configuration.
512  rv = caps->ConfigureDone();
513  NS_ENSURE_SUCCESS(rv, rv);
514 
515  caps.forget(aCapabilities);
516  return NS_OK;
517 }
518 
519 /* readonly attribute sbIDeviceContent content; */
520 NS_IMETHODIMP sbMockDevice::GetContent(sbIDeviceContent * *aContent)
521 {
522  nsresult rv;
523  if (!mContent) {
524  nsRefPtr<sbDeviceContent> deviceContent = sbDeviceContent::New();
525  NS_ENSURE_TRUE(deviceContent, NS_ERROR_OUT_OF_MEMORY);
526  rv = deviceContent->Initialize();
527  NS_ENSURE_SUCCESS(rv, rv);
528  mContent = deviceContent;
529 
530  // Create a device volume.
531  nsRefPtr<sbBaseDeviceVolume> volume;
532  rv = sbBaseDeviceVolume::New(getter_AddRefs(volume), this);
533  NS_ENSURE_SUCCESS(rv, rv);
534 
535  // Set the volume GUID.
536  char volumeGUID[NSID_LENGTH];
537  nsID* deviceID;
538  rv = GetId(&deviceID);
539  NS_ENSURE_SUCCESS(rv, rv);
540  deviceID->ToProvidedString(volumeGUID);
541  NS_Free(deviceID);
542  rv = volume->SetGUID(NS_ConvertUTF8toUTF16(volumeGUID));
543  NS_ENSURE_SUCCESS(rv, rv);
544 
545  // Add the volume.
546  rv = AddVolume(volume);
547  NS_ENSURE_SUCCESS(rv, rv);
548 
549  // Set the primary and default volume.
550  {
551  nsAutoLock autoVolumeLock(mVolumeLock);
552  mPrimaryVolume = volume;
553  mDefaultVolume = volume;
554  }
555 
556  // make a mock library too
557  NS_NAMED_LITERAL_STRING(LIBID, "mock-library.mock-device");
558  nsCOMPtr<sbIDeviceLibrary> devLib;
559  rv = CreateDeviceLibrary(LIBID, nsnull, getter_AddRefs(devLib));
560  NS_ENSURE_SUCCESS(rv, rv);
561 
562  // Set the volume device library.
563  rv = volume->SetDeviceLibrary(devLib);
564  NS_ENSURE_SUCCESS(rv, rv);
565 
566  rv = AddLibrary(devLib);
567  NS_ENSURE_SUCCESS(rv, rv);
568  }
569  NS_ADDREF(*aContent = mContent);
570  return NS_OK;
571 }
572 
573 /* attribute sbIDeviceLibrary defaultLibrary; */
574 NS_IMETHODIMP
576 {
577  return sbBaseDevice::GetDefaultLibrary(aDefaultLibrary);
578 }
579 
580 NS_IMETHODIMP
582 {
583  return sbBaseDevice::SetDefaultLibrary(aDefaultLibrary);
584 }
585 
586 /* readonly attribute sbIDeviceLibrary primaryLibrary; */
587 NS_IMETHODIMP
589 {
590  return sbBaseDevice::GetPrimaryLibrary(aPrimaryLibrary);
591 }
592 
593 /* readonly attribute nsIPropertyBag2 parameters; */
594 NS_IMETHODIMP sbMockDevice::GetParameters(nsIPropertyBag2 * *aParameters)
595 {
596  nsresult rv;
597 
598  nsCOMPtr<nsIWritablePropertyBag> writeBag =
599  do_CreateInstance("@mozilla.org/hash-property-bag;1", &rv);
600  NS_ENSURE_SUCCESS(rv, rv);
601 
602  nsCOMPtr<nsIWritableVariant> deviceType =
603  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
604  NS_ENSURE_SUCCESS(rv, rv);
605 
606  // Pretend like we're an MTP device.
607  rv = deviceType->SetAsAString(NS_LITERAL_STRING("MTP"));
608  NS_ENSURE_SUCCESS(rv, rv);
609 
610  rv = writeBag->SetProperty(NS_LITERAL_STRING("DeviceType"),
611  deviceType);
612  NS_ENSURE_SUCCESS(rv, rv);
613 
614  nsCOMPtr<nsIPropertyBag2> propBag = do_QueryInterface(writeBag, &rv);
615  NS_ENSURE_SUCCESS(rv, rv);
616 
617  propBag.forget(aParameters);
618 
619  return NS_OK;
620 }
621 
622 NS_IMETHODIMP sbMockDevice::GetProperties(sbIDeviceProperties * *theProperties)
623 {
624  nsresult rv = NS_ERROR_UNEXPECTED;
625 
626  if(!mProperties) {
627  nsCOMPtr<sbIDeviceProperties> properties =
628  do_CreateInstance("@songbirdnest.com/Songbird/Device/DeviceProperties;1", &rv);
629  NS_ENSURE_SUCCESS(rv, rv);
630 
631  rv = properties->InitFriendlyName(NS_LITERAL_STRING("Testing Device"));
632  NS_ENSURE_SUCCESS(rv, rv);
633 
634  rv = properties->InitVendorName(NS_LITERAL_STRING("ACME Inc."));
635  NS_ENSURE_SUCCESS(rv, rv);
636 
637  nsCOMPtr<nsIWritableVariant> modelNumber =
638  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
639  NS_ENSURE_SUCCESS(rv, rv);
640 
641  rv = modelNumber->SetAsString("ACME 9000");
642  NS_ENSURE_SUCCESS(rv, rv);
643 
644  rv = properties->InitModelNumber(modelNumber);
645  NS_ENSURE_SUCCESS(rv, rv);
646 
647  nsCOMPtr<nsIWritableVariant> serialNumber =
648  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
649  NS_ENSURE_SUCCESS(rv, rv);
650 
651  rv = serialNumber->SetAsString("ACME-9000-0001-2000-3000");
652  NS_ENSURE_SUCCESS(rv, rv);
653 
654  rv = properties->InitSerialNumber(serialNumber);
655  NS_ENSURE_SUCCESS(rv, rv);
656 
657  rv = properties->InitFirmwareVersion(NS_LITERAL_STRING("1.0.0.0"));
658  NS_ENSURE_SUCCESS(rv, rv);
659 
660  nsCOMPtr<nsIWritablePropertyBag> writeBag =
661  do_CreateInstance("@mozilla.org/hash-property-bag;1", &rv);
662  NS_ENSURE_SUCCESS(rv, rv);
663 
664  nsCOMPtr<nsIWritableVariant> freeSpace =
665  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
666  NS_ENSURE_SUCCESS(rv, rv);
667 
668  rv = freeSpace->SetAsString("17179869184");
669  NS_ENSURE_SUCCESS(rv, rv);
670 
671  rv = writeBag->SetProperty(NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#freeSpace"),
672  freeSpace);
673  NS_ENSURE_SUCCESS(rv, rv);
674 
675  nsCOMPtr<nsIWritableVariant> totalUsedSpace =
676  do_CreateInstance("@songbirdnest.com/Songbird/Variant;1", &rv);
677  NS_ENSURE_SUCCESS(rv, rv);
678 
679  rv = totalUsedSpace->SetAsString("4294967296");
680  NS_ENSURE_SUCCESS(rv, rv);
681 
682  rv = writeBag->SetProperty(NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#totalUsedSpace"),
683  totalUsedSpace);
684  NS_ENSURE_SUCCESS(rv, rv);
685 
686  nsCOMPtr<nsIPropertyBag2> propBag = do_QueryInterface(writeBag, &rv);
687  NS_ENSURE_SUCCESS(rv, rv);
688 
689  rv = properties->InitDeviceProperties(propBag);
690  NS_ENSURE_SUCCESS(rv, rv);
691 
692  rv = properties->InitDone();
693  NS_ENSURE_SUCCESS(rv, rv);
694 
696  }
697 
698  NS_ADDREF(*theProperties = mProperties);
699 
700  return NS_OK;
701 }
702 
703 NS_IMETHODIMP sbMockDevice::SubmitRequest(PRUint32 aRequestType,
704  nsIPropertyBag2 *aRequestParameters)
705 {
706  return sbBaseDevice::SubmitRequest(aRequestType, aRequestParameters);
707 }
708 
710 {
711  std::insert_iterator<std::vector<nsRefPtr<sbRequestItem> > >
712  insertIter(mBatch, mBatch.end());
713  std::copy(aBatch.begin(), aBatch.end(), insertIter);
714 
715  /* don't process, let the js deal with it */
716  return NS_OK;
717 }
718 
719 NS_IMETHODIMP sbMockDevice::CancelRequests()
720 {
721  return mRequestThreadQueue->CancelRequests();
722 }
723 
724 NS_IMETHODIMP sbMockDevice::Eject()
725 {
726  return NS_ERROR_NOT_IMPLEMENTED;
727 }
728 
729 NS_IMETHODIMP
730 sbMockDevice::GetIsDirectTranscoding(PRBool* aIsDirect)
731 {
732  return sbBaseDevice::GetIsDirectTranscoding(aIsDirect);
733 }
734 
735 NS_IMETHODIMP sbMockDevice::GetIsBusy(PRBool *aIsBusy)
736 {
737  nsCOMPtr<nsIVariant> busyVariant;
738  nsresult rv =
739  GetPreference(NS_LITERAL_STRING("testing.busy"),
740  getter_AddRefs(busyVariant));
741  NS_ENSURE_SUCCESS(rv, rv);
742 
743  PRUint16 dataType = 0;
744  rv = busyVariant->GetDataType(&dataType);
745  NS_ENSURE_SUCCESS(rv, rv);
746 
747  if(dataType == nsIDataType::VTYPE_BOOL) {
748  rv = busyVariant->GetAsBool(aIsBusy);
749  NS_ENSURE_SUCCESS(rv, rv);
750  }
751  else {
752  rv = sbBaseDevice::GetIsBusy(aIsBusy);
753  NS_ENSURE_SUCCESS(rv, rv);
754  }
755 
756  return NS_OK;
757 }
758 
759 NS_IMETHODIMP sbMockDevice::GetCanDisconnect(PRBool *aCanDisconnect)
760 {
761  return sbBaseDevice::GetCanDisconnect(aCanDisconnect);
762 }
763 
764 NS_IMETHODIMP sbMockDevice::GetState(PRUint32 *aState)
765 {
766  return sbBaseDevice::GetState(aState);
767 }
768 
769 NS_IMETHODIMP sbMockDevice::SetState(PRUint32 aState)
770 {
771  return sbBaseDevice::SetState(aState);
772 }
773 
774 NS_IMETHODIMP sbMockDevice::GetPreviousState(PRUint32 *aState)
775 {
776  return sbBaseDevice::GetPreviousState(aState);
777 }
778 
779 NS_IMETHODIMP sbMockDevice::SyncLibraries()
780 {
782 }
783 
784 NS_IMETHODIMP sbMockDevice::SupportsMediaItem(
785  sbIMediaItem* aMediaItem,
787 {
788  return sbBaseDevice::SupportsMediaItem(aMediaItem, aCallback);
789 }
790 
791 
792 /****************************** sbIMockDevice ******************************/
793 
794 #define SET_PROP(type, name) \
795  rv = bag->SetPropertyAs ## type(NS_LITERAL_STRING(#name), \
796  transferRequest->name); \
797  NS_ENSURE_SUCCESS(rv, rv);
798 
799 /* nsIPropertyBag2 PopRequest (); */
800 NS_IMETHODIMP sbMockDevice::PopRequest(nsIPropertyBag2 **_retval)
801 {
802  // while it's easier to reuse PeekRequest, that sort of defeats the purpose
803  // of testing.
804  NS_ENSURE_ARG_POINTER(_retval);
805 
806  nsresult rv;
807 
808  if (mBatch.empty()) {
809  return NS_ERROR_NOT_AVAILABLE;
810  }
811  nsRefPtr<sbRequestItem> requestItem = *mBatch.begin();
812  mBatch.erase(mBatch.begin());
813 
814 
815  nsCOMPtr<nsIWritablePropertyBag2> bag =
816  do_CreateInstance(NS_HASH_PROPERTY_BAG_CONTRACTID, &rv);
817  NS_ENSURE_SUCCESS(rv, rv);
818 
819  const PRInt32 batchCount = mBatch.size();
820 
821  rv = bag->SetPropertyAsInt32(NS_LITERAL_STRING("requestType"),
822  requestItem->GetType());
823  rv = bag->SetPropertyAsInt32(NS_LITERAL_STRING("batchCount"), batchCount);
824  NS_ENSURE_SUCCESS(rv, rv);
825 
826  const PRInt32 batchIndex = requestItem->GetBatchIndex();
827 
828  rv = bag->SetPropertyAsInt32(NS_LITERAL_STRING("batchIndex"), batchIndex);
829  NS_ENSURE_SUCCESS(rv, rv);
830 
831  const PRInt32 requestId = requestItem->GetRequestId();
832 
833  rv = bag->SetPropertyAsInt32(NS_LITERAL_STRING("itemTransferID"),
834  requestId);
835  NS_ENSURE_SUCCESS(rv, rv);
836 
837  if (requestItem->GetType() >= sbRequestThreadQueue::USER_REQUEST_TYPES) {
838  TransferRequest * transferRequest =
839  static_cast<TransferRequest *>(requestItem.get());
840  SET_PROP(Interface, item);
841  SET_PROP(Interface, list);
842  SET_PROP(Interface, data);
843  SET_PROP(Uint32, index);
844  SET_PROP(Uint32, otherIndex);
845  }
846  return CallQueryInterface(bag, _retval);
847 }
848 
849 NS_IMETHODIMP sbMockDevice::SetWarningDialogEnabled(const nsAString & aWarning, PRBool aEnabled)
850 {
851  return sbBaseDevice::SetWarningDialogEnabled(aWarning, aEnabled);
852 }
853 
854 NS_IMETHODIMP sbMockDevice::GetWarningDialogEnabled(const nsAString & aWarning, PRBool *_retval)
855 {
856  return sbBaseDevice::GetWarningDialogEnabled(aWarning, _retval);
857 }
858 
859 NS_IMETHODIMP sbMockDevice::ResetWarningDialogs()
860 {
862 }
863 
864 NS_IMETHODIMP sbMockDevice::OpenInputStream(nsIURI* aURI,
865  nsIInputStream** retval)
866 {
867  return sbBaseDevice::OpenInputStream(aURI, retval);
868 }
869 
870 NS_IMETHODIMP sbMockDevice::GetCurrentStatus(sbIDeviceStatus * *aCurrentStatus)
871 {
872  NS_ENSURE_ARG(aCurrentStatus);
873  return mStatus->GetCurrentStatus(aCurrentStatus);
874 }
875 
876 
877 /* void Format(); */
878 NS_IMETHODIMP sbMockDevice::Format()
879 {
880  return NS_ERROR_NOT_IMPLEMENTED;
881 }
882 /* readonly attribute boolean supportsReformat; */
883 NS_IMETHODIMP sbMockDevice::GetSupportsReformat(PRBool *_retval)
884 {
885  NS_ENSURE_ARG_POINTER(_retval);
886  *_retval = PR_FALSE;
887  return NS_OK;
888 }
889 
890 NS_IMETHODIMP
892  sbILibraryChangeset* aExportChangeset)
893 {
894  return sbBaseDevice::ExportToDevice(aDevLibrary, aExportChangeset);
895 }
896 
897 NS_IMETHODIMP
898 sbMockDevice::ImportFromDevice(sbILibrary * aImportToLibrary,
899  sbILibraryChangeset * aImportChangeset)
900 {
901  return sbBaseDevice::ImportFromDevice(aImportToLibrary, aImportChangeset);
902 }
903 
PRLock * mVolumeLock
Definition: sbBaseDevice.h:873
NS_IMETHOD GetPreference(const nsAString &aPrefName, nsIVariant **_retval)
NS_SCRIPTABLE NS_IMETHOD ResetWarningDialogs(void)
return NS_OK
NS_IMETHOD Format(void)
nsCOMPtr< sbDeviceContent > mContent
Definition: sbMockDevice.h:51
nsresult CreateDeviceLibrary(const nsAString &aId, nsIURI *aLibraryLocation, sbIDeviceLibrary **_retval)
const PRUint32 FUNCTION_VIDEO_PLAYBACK
nsAutoPtr< sbDeviceStatusHelper > mStatus
Definition: sbBaseDevice.h:689
#define SB_IMAGESIZE_CONTRACTID
nsresult ProcessBatch(Batch &aBatch)
[UNIMPLEMENTED UNTIL AFTER 0.3]
NS_IMETHOD GetIsDirectTranscoding(PRBool *aIsDirect)
nsRefPtr< sbDeviceRequestThreadQueue > mRequestThreadQueue
Definition: sbBaseDevice.h:730
nsCOMPtr< sbIDeviceProperties > mProperties
Definition: sbMockDevice.h:52
NS_IMETHOD GetPrimaryLibrary(sbIDeviceLibrary **aPrimaryLibrary)
nsresult Init()
NS_IMETHOD GetPreviousState(PRUint32 *aState)
NS_SCRIPTABLE NS_IMETHOD SetWarningDialogEnabled(const nsAString &aWarning, PRBool aEnabled)
NS_SCRIPTABLE NS_IMETHOD OpenInputStream(nsIURI *aURI, nsIInputStream **retval)
nsRefPtr< sbBaseDeviceVolume > mPrimaryVolume
Definition: sbBaseDevice.h:879
NS_SCRIPTABLE NS_IMETHOD GetWarningDialogEnabled(const nsAString &aWarning, PRBool *_retval)
NS_IMETHOD SyncLibraries(void)
Songbird Variant Utility Definitions.
[UNIMPLEMENTED UNTIL AFTER 0.3]
#define SET_PROP(type, name)
NS_IMETHOD Connect()
nsRefPtr< sbBaseDeviceVolume > mDefaultVolume
Definition: sbBaseDevice.h:880
#define SB_IDEVCAPAUDIOSTREAM_CONTRACTID
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
#define DEVICE_PREF_BRANCH
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
#define SB_IDEVCAPVIDEOSTREAM_CONTRACTID
NS_IMETHOD GetState(PRUint32 *aState)
std::vector< nsRefPtr< sbRequestItem > > mBatch
Definition: sbMockDevice.h:53
#define SONGBIRD_DEVICECAPABILITIES_CONTRACTID
const_iterator end() const
nsresult ReqProcessingStart()
NS_IMETHOD SupportsMediaItem(sbIMediaItem *aMediaItem, sbIDeviceSupportsItemCallback *aCallback)
NS_IMETHOD Eject(void)
NS_DECL_ISUPPORTS static NS_DECL_SBIDEVICECONTENT sbDeviceContent * New()
NS_IMETHOD GetDefaultLibrary(sbIDeviceLibrary **aDefaultLibrary)
_updateTextAndScrollDataForFrame aContent
const unsigned long STATE_IDLE
Definition: sbIDevice.idl:220
NS_IMETHOD Disconnect()
NS_IMETHOD CancelRequests()
PRBool mIsConnected
Definition: sbMockDevice.h:49
Media library abstraction.
Definition: sbILibrary.idl:82
attribute unsigned long state
Definition: sbIDevice.idl:217
NS_IMETHOD GetIsBusy(PRBool *aIsBusy)
#define SB_IDEVCAPRANGE_CONTRACTID
NS_IMETHOD ExportToDevice(sbIDeviceLibrary *aDevLibrary, sbILibraryChangeset *aChangeset)
readonly attribute sbIDeviceProperties properties
Definition: sbIDevice.idl:168
const unsigned long EVENT_DEVICE_REMOVED
nsresult AddVolume(sbBaseDeviceVolume *aVolume)
nsresult RemoveLibrary(sbIDeviceLibrary *aDevLib)
NS_IMETHOD GetSupportsReformat(PRBool *_retval)
_updateCookies aName
countRef value
Definition: FeedWriter.js:1423
#define SB_IVIDEOFORMATTYPE_CONTRACTID
NS_IMETHOD SubmitRequest(PRUint32 aRequest, nsIPropertyBag2 *aRequestParameters)
NS_IMETHOD GetCanDisconnect(PRBool *aCanDisconnect)
PRUint32 mState
Definition: sbBaseDevice.h:684
static NS_DECL_ISUPPORTS nsresult New(sbBaseDeviceVolume **aVolume, sbBaseDevice *aDevice)
Interface that defines a single item of media in the system.
NS_IMETHOD ImportFromDevice(sbILibrary *aImportToLibrary, sbILibraryChangeset *aImportChangeset)
restoreWindow aState
NS_IMETHOD SetState(PRUint32 aState)
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
const_iterator begin() const
NS_IMETHOD SetPreference(const nsAString &aPrefName, nsIVariant *aPrefValue)
void FinalizeDeviceLibrary(sbIDeviceLibrary *aDevLib)
NS_IMETHOD SetDefaultLibrary(sbIDeviceLibrary *aDefaultLibrary)
nsresult RemoveVolume(sbBaseDeviceVolume *aVolume)
nsresult AddLibrary(sbIDeviceLibrary *aDevLib)