sbBaseDeviceMarshall.cpp
Go to the documentation of this file.
1 /*
2  //
3  // BEGIN SONGBIRD GPL
4  //
5  // This file is part of the Songbird web player.
6  //
7  // Copyright(c) 2005-2008 POTI, Inc.
8  // http://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 
27 #include "sbBaseDeviceMarshall.h"
28 #include <nsISupportsPrimitives.h>
29 #include <nsIMutableArray.h>
30 #include <nsICategoryManager.h>
31 #include <nsComponentManagerUtils.h>
32 #include <nsServiceManagerUtils.h>
33 #include <sbIDeviceControllerRegistrar.h>
34 #include <sbIDeviceController.h>
35 #include <sbIDeviceCompatibility.h>
36 #include <nsIPropertyBag.h>
37 #include <nsIUUIDGenerator.h>
38 
39 sbBaseDeviceMarshall::sbBaseDeviceMarshall(nsACString const & categoryName) :
40  mCategoryName(categoryName), mIsMonitoring(PR_TRUE)
41 {
42 }
43 
45 {
46  NS_ASSERTION(!mIsMonitoring,
47  "A device marshaller is being released with monitoring enabled");
48 }
49 
51 {
52  nsIArray * controllers = GetControllers();
53  nsCOMPtr<nsISimpleEnumerator> enumerator;
54  if (controllers
55  && NS_SUCCEEDED(controllers->Enumerate(getter_AddRefs(enumerator)))
56  && enumerator) {
57  PRBool more;
58  while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
59  nsCOMPtr<nsISupports> comPtr;
60  if (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(comPtr))) && comPtr) {
61  nsCOMPtr<sbIDeviceController> controller(do_QueryInterface(comPtr));
62  registrar->RegisterController(controller);
63  }
64  }
65  }
66 }
67 
68 inline
69 void AppendDeviceController(nsCOMPtr<nsISupports> & ptr,
70  nsCOMPtr<nsIMutableArray> & controllers)
71 {
72  // Get the string value from the category entry
73  nsCOMPtr<nsISupportsCString> stringValue(do_QueryInterface(ptr));
74  nsCString controllerName;
75  nsresult rv;
76  if (stringValue && NS_SUCCEEDED(stringValue->GetData(controllerName))) {
77  nsCOMPtr<sbIDeviceController> deviceController =
78  do_CreateInstance(controllerName.get() , &rv);
79  NS_ENSURE_SUCCESS(rv, /* void */);
80 
81  // check if the device manager already has a matching controller
82  nsCOMPtr<sbIDeviceControllerRegistrar> controllerRegistrar =
83  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
84  NS_ENSURE_SUCCESS(rv, /* void */);
85 
86  nsID* controllerId = nsnull;
87  rv = deviceController->GetId(&controllerId);
88  NS_ENSURE_SUCCESS(rv, /* void */);
89 
90  nsCOMPtr<sbIDeviceController> existingController;
91  rv = controllerRegistrar->GetController(controllerId,
92  getter_AddRefs(existingController));
93  NS_Free(controllerId);
94 
95  if (NS_SUCCEEDED(rv) && existingController) {
96  deviceController = existingController;
97  }
98 
99  controllers->AppendElement(deviceController, PR_FALSE);
100  }
101 }
102 static nsresult CopyCategoriesToArray(nsCOMPtr<nsISimpleEnumerator> & enumerator,
103  nsCOMPtr<nsIMutableArray> & controllers)
104 {
105  // Start with a fresh array
106  nsresult rv = controllers->Clear();
107  NS_ENSURE_SUCCESS(rv, rv);
108 
109  // Enumerate the category entries
110  PRBool more;
111  while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
112  nsCOMPtr<nsISupports> ptr;
113  if (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(ptr))) && ptr) {
115  controllers);
116  NS_ENSURE_SUCCESS(rv, rv);
117  }
118  }
119  return rv;
120 }
121 
123 {
124  if (!mControllers) {
125  nsresult rv;
126  mControllers = do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
127  if (NS_FAILED(rv)) {
128  NS_ERROR("unable to create an nsArray");
129  return nsnull;
130  }
131  }
132  nsCOMPtr<nsIMutableArray> controllers(do_QueryInterface(mControllers));
133  nsCOMPtr<nsISimpleEnumerator> categoryEnumerator;
134  if (NS_SUCCEEDED(GetCategoryManagerEnumerator(categoryEnumerator))) {
135  if (NS_FAILED(CopyCategoriesToArray(categoryEnumerator, controllers)))
136  return nsnull;
137  }
138  return mControllers;
139 }
140 
141 nsresult sbBaseDeviceMarshall::GetCategoryManagerEnumerator(nsCOMPtr<nsISimpleEnumerator> & enumerator)
142 {
143  nsCOMPtr<nsICategoryManager> cm(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
144  return cm->EnumerateCategory(PromiseFlatCString(mCategoryName).get(), getter_AddRefs(enumerator));
145 }
146 
150 inline
152  sbIDeviceCompatibility * comp2)
153 {
154  PRUint32 compVal1 = sbIDeviceCompatibility::INCOMPATIBLE;
155  PRUint32 compVal2 = sbIDeviceCompatibility::INCOMPATIBLE;
156 
157  return (comp1 && NS_SUCCEEDED(comp1->GetCompatibility(&compVal1))) ||
158  ((comp2 && NS_SUCCEEDED(comp2->GetCompatibility(&compVal2))) &&
159  compVal2 > compVal1 &&
161 }
162 
164  nsIPropertyBag * deviceParameters)
165 {
166  nsCOMPtr<sbIDeviceCompatibility> compatibility;
167  if (NS_SUCCEEDED(controller->GetCompatibility(deviceParameters,
168  getter_AddRefs(compatibility)))
169  && compatibility) {
170  if (!mCompatibility && CompareCompatibility(mCompatibility, compatibility)) {
171  SetBestMatch(controller, compatibility);
172  }
173  }
174  return PR_TRUE;
175 }
176 
178  CompatibilityComparer & deviceComparer)
179 {
180  // Get the list of controllers
181  nsIArray * controllers = GetControllers();
182  nsCOMPtr<nsISimpleEnumerator> enumerator;
183  if (controllers
184  && NS_SUCCEEDED(controllers->Enumerate(getter_AddRefs(enumerator)))
185  && enumerator) {
186  // Enumerate the list of controllers
187  PRBool more;
188  while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
189  nsCOMPtr<sbIDeviceController> controller;
190  if (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(controller)))
191  && controller) {
192  nsCOMPtr<sbIDeviceCompatibility> compatibilityObj;
193  if (!deviceComparer.Compare(controller, deviceParams))
194  break;
195  }
196  }
197  }
198  // This may be null if none were found
199  return deviceComparer.GetBestMatch();
200 }
var registrar
nsIArray * GetControllers() const
PRBool CompareCompatibility(sbIDeviceCompatibility *comp1, sbIDeviceCompatibility *comp2)
virtual PRBool Compare(sbIDeviceController *controller, nsIPropertyBag *deviceParams)
sbBaseDeviceMarshall(nsACString const &categoryName)
sbIDeviceController * FindCompatibleControllers(nsIPropertyBag *deviceParams)
[UNIMPLEMENTED UNTIL AFTER 0.3]
static nsresult CopyCategoriesToArray(nsCOMPtr< nsISimpleEnumerator > &enumerator, nsCOMPtr< nsIMutableArray > &controllers)
void RegisterControllers(sbIDeviceControllerRegistrar *registrar)
[UNIMPLEMENTED UNTIL AFTER 0.3]
[UNIMPLEMENTED UNTIL AFTER 0.3]
void AppendDeviceController(nsCOMPtr< nsISupports > &ptr, nsCOMPtr< nsIMutableArray > &controllers)
sbIDeviceController * GetBestMatch() const
const unsigned long INCOMPATIBLE
var cm
void SetBestMatch(sbIDeviceController *deviceController, sbIDeviceCompatibility *compatibility)