Bug 777084 - Stop returning arrays from DeviceStorage.getDeviceStorage(). r=sicking
authorDoug Turner <dougt@dougt.org>
Wed, 01 Aug 2012 23:32:11 -0700
changeset 101201 cb017d0510296e4f873855f4c9ab09129a64a578
parent 101200 d628a6d43f6c00a9b0d5eae5bda4cbf4addce109
child 101202 865a6f2d3a831e77a6756780acd1d3dbc501bdfa
child 101229 074fb996dfd77c993b1de2f91070f4db78714a34
push id12895
push userdougt@mozilla.com
push dateThu, 02 Aug 2012 06:56:26 +0000
treeherdermozilla-inbound@cb017d051029 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs777084
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 777084 - Stop returning arrays from DeviceStorage.getDeviceStorage(). r=sicking
dom/base/Navigator.cpp
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/test/test_basic.html
dom/devicestorage/test/test_dotdot.html
dom/devicestorage/test/test_enumerate.html
dom/devicestorage/test/test_enumerateMultipleContinue.html
dom/devicestorage/test/test_enumerateNoParam.html
dom/devicestorage/test/test_enumerateOptions.html
dom/devicestorage/test/test_lastModificationFilter.html
dom/devicestorage/test/test_overwrite.html
dom/devicestorage/test/test_sanity.html
dom/interfaces/devicestorage/nsIDOMNavigatorDeviceStorage.idl
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -873,41 +873,37 @@ Navigator::MozIsLocallyAvailable(const n
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
   return httpChannel->GetRequestSucceeded(aIsAvailable);
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigatorDeviceStorage
 //*****************************************************************************
 
-NS_IMETHODIMP Navigator::GetDeviceStorage(const nsAString &aType, nsIVariant** _retval)
+NS_IMETHODIMP Navigator::GetDeviceStorage(const nsAString &aType, nsIDOMDeviceStorage** _retval)
 {
   if (!Preferences::GetBool("device.storage.enabled", false)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
 
   if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
     return NS_ERROR_FAILURE;
   }
 
-  nsTArray<nsRefPtr<nsDOMDeviceStorage> > stores;
-  nsDOMDeviceStorage::CreateDeviceStoragesFor(win, aType, stores);
-
-  nsCOMPtr<nsIWritableVariant> result = do_CreateInstance("@mozilla.org/variant;1");
-  NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
+  nsRefPtr<nsDOMDeviceStorage> storage;
+  nsDOMDeviceStorage::CreateDeviceStoragesFor(win, aType, getter_AddRefs(storage));
 
-  result->SetAsArray(nsIDataType::VTYPE_INTERFACE,
-                     &NS_GET_IID(nsIDOMDeviceStorage),
-                     stores.Length(),
-                     const_cast<void*>(static_cast<const void*>(stores.Elements())));
-  result.forget(_retval);
+  if (!storage) {
+    return NS_OK;
+  }
 
-  mDeviceStorageStores.AppendElements(stores);
+  NS_ADDREF(*_retval = storage.get());
+  mDeviceStorageStores.AppendElement(storage);                                                                                                                                                                                              
   return NS_OK;
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigatorGeolocation
 //*****************************************************************************
 
 NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -23,23 +23,23 @@ public:
   NS_DECL_NSIFILEUPDATELISTENER
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIDOMEVENTTARGET
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
   NS_DECL_EVENT_HANDLER(change)
 
   nsDOMDeviceStorage();
 
-  nsresult Init(nsPIDOMWindow* aWindow, const nsAString &aType, const PRInt32 aIndex);
+  nsresult Init(nsPIDOMWindow* aWindow, const nsAString &aType);
 
-  void SetRootFileForType(const nsAString& aType, const PRInt32 aIndex);
+  void SetRootFileForType(const nsAString& aType);
 
   static void CreateDeviceStoragesFor(nsPIDOMWindow* aWin,
                                       const nsAString &aType,
-                                      nsTArray<nsRefPtr<nsDOMDeviceStorage> > &aStores);
+                                      nsDOMDeviceStorage** aStore);
   void Shutdown();
 
 private:
   ~nsDOMDeviceStorage();
 
   nsresult GetInternal(const JS::Value & aName,
                        JSContext* aCx,
                        nsIDOMDOMRequest** aRetval,
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -275,17 +275,17 @@ DeviceStorageFile::collectFilesInternal(
     }
   }
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS0(DeviceStorageFile)
 
 
 void
-nsDOMDeviceStorage::SetRootFileForType(const nsAString& aType, const PRInt32 aIndex)
+nsDOMDeviceStorage::SetRootFileForType(const nsAString& aType)
 {
   nsCOMPtr<nsIFile> f;
   nsCOMPtr<nsIProperties> dirService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
   NS_ASSERTION(dirService, "Must have directory service");
 
 #ifdef MOZ_WIDGET_GONK
   mFile = nullptr;
 
@@ -307,69 +307,51 @@ nsDOMDeviceStorage::SetRootFileForType(c
   if (state != nsIVolume::STATE_MOUNTED) {
     return;
   }
 #endif
 
   // Picture directory
   if (aType.Equals(NS_LITERAL_STRING("pictures"))) {
 #ifdef MOZ_WIDGET_GONK
-    if (aIndex == 0) {
-      NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/DCIM"), false, getter_AddRefs(f));
-    }
+    NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/DCIM"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
-    if (aIndex == 0) {
-      dirService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
-    if (aIndex == 0) {
-      dirService->Get(NS_UNIX_XDG_PICTURES_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_UNIX_XDG_PICTURES_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
 
   // Video directory
   if (aType.Equals(NS_LITERAL_STRING("videos"))) {
 #ifdef MOZ_WIDGET_GONK
-    if (aIndex == 0) {
-      NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/Movies"), false, getter_AddRefs(f));
-    }
+    NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/Movies"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
-    if (aIndex == 0) {
-      dirService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
-    if (aIndex == 0) {
-      dirService->Get(NS_UNIX_XDG_VIDEOS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_UNIX_XDG_VIDEOS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
 
   // Music directory
   if (aType.Equals(NS_LITERAL_STRING("music"))) {
 #ifdef MOZ_WIDGET_GONK
-    if (aIndex == 0) {
-      NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/Music"), false, getter_AddRefs(f));
-    }
+    NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/Music"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
-    if (aIndex == 0) {
-      dirService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
-    if (aIndex == 0) {
-      dirService->Get(NS_UNIX_XDG_MUSIC_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    }
+    dirService->Get(NS_UNIX_XDG_MUSIC_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
 
   // in testing, we have access to a few more directory locations
   if (mozilla::Preferences::GetBool("device.storage.testing", false)) {
 
     // testing directory
-    if (aType.Equals(NS_LITERAL_STRING("testing")) && aIndex == 0) {
+    if (aType.Equals(NS_LITERAL_STRING("testing"))) {
       dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
       if (f) {
 	f->AppendRelativeNativePath(NS_LITERAL_CSTRING("device-storage-testing"));
 	f->Create(nsIFile::DIRECTORY_TYPE, 0777);
        f->Normalize();
       }
     }
   } 
@@ -1313,21 +1295,21 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEve
 NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
 
 nsDOMDeviceStorage::nsDOMDeviceStorage()
   : mIsWatchingFile(false)
 { }
 
 nsresult
-nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType, const PRInt32 aIndex)
+nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType)
 {
   NS_ASSERTION(aWindow, "Must have a content dom");
 
-  SetRootFileForType(aType, aIndex);
+  SetRootFileForType(aType);
   if (!mFile) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   BindToOwner(aWindow);
 
   // Grab the uri of the document
   nsCOMPtr<nsIDOMDocument> domdoc;
@@ -1362,26 +1344,21 @@ nsDOMDeviceStorage::Shutdown()
       mFile->Unwatch(this);
     }
   }
 }
 
 void
 nsDOMDeviceStorage::CreateDeviceStoragesFor(nsPIDOMWindow* aWin,
                                             const nsAString &aType,
-                                            nsTArray<nsRefPtr<nsDOMDeviceStorage> > &aStores)
+                                            nsDOMDeviceStorage** aStore)
 {
-  PRInt32 index = 0;
-  while (1) {
-    nsresult rv;
-    nsRefPtr<nsDOMDeviceStorage> storage = new nsDOMDeviceStorage();
-    rv = storage->Init(aWin, aType, index++);
-    if (NS_FAILED(rv))
-      break;
-    aStores.AppendElement(storage);
+  nsRefPtr<nsDOMDeviceStorage> storage = new nsDOMDeviceStorage();
+  if (NS_SUCCEEDED(storage->Init(aWin, aType))) {
+    NS_ADDREF(*aStore = storage);
   }
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorage::Add(nsIDOMBlob *aBlob, nsIDOMDOMRequest * *_retval)
 {
   // possible race here w/ unique filename
   char buffer[128];
--- a/dom/devicestorage/test/test_basic.html
+++ b/dom/devicestorage/test/test_basic.html
@@ -49,17 +49,17 @@ function getAfterDeleteError(e) {
 }
 
 function deleteSuccess(e) {
 
   ok(e.target.result == gFileName, "File name should match");
   dump(e.target.result + "\n")
 
   var storage = navigator.getDeviceStorage("testing");
-  request = storage[0].get(e.target.result);
+  request = storage.get(e.target.result);
   request.onsuccess = getAfterDeleteSuccess;
   request.onerror = getAfterDeleteError;
 
 }
 
 function deleteError(e) {
   ok(false, "deleteError was called : " + e.target.error.name);
   devicestorage_cleanup();
@@ -72,17 +72,17 @@ function getSuccess(e) {
   ok(e.target.result.name == gFileName, "File name should match");
 
   var name = e.target.result.name;
 
   gFileReader.readAsArrayBuffer(gDataBlob);
   gFileReader.onload = function(e) {
     readerCallback(e);
 
-    request = storage[0].delete(name)
+    request = storage.delete(name)
     request.onsuccess = deleteSuccess;
     request.onerror = deleteError;
   }
 }
 
 function readerCallback(e) {
 
   ab = e.target.result;
@@ -97,34 +97,34 @@ function getError(e) {
   devicestorage_cleanup();
 }
 
 function addSuccess(e) {
 
   ok(e.target.result == gFileName, "File name should match");
 
   var storage = navigator.getDeviceStorage("testing");
-  request = storage[0].get(gFileName);
+  request = storage.get(gFileName);
   request.onsuccess = getSuccess;
   request.onerror = getError;
 
   ok(true, "addSuccess was called");
 }
 
 function addError(e) {
   ok(false, "addError was called : " + e.target.error.name);
   devicestorage_cleanup();
 }
 
 ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
 
 var storage = navigator.getDeviceStorage("testing");
 ok(storage, "Should have gotten a storage");
 
-request = storage[0].addNamed(gDataBlob, "devicestorage/hi");
+request = storage.addNamed(gDataBlob, "devicestorage/hi");
 ok(request, "Should have a non-null request");
 
 request.onsuccess = addSuccess;
 request.onerror = addError;
 
 </script>
 </pre>
 </body>
--- a/dom/devicestorage/test/test_dotdot.html
+++ b/dom/devicestorage/test/test_dotdot.html
@@ -20,17 +20,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 devicestorage_setup();
 
 function testingStorage() {
-  return navigator.getDeviceStorage("testing")[0];
+  return navigator.getDeviceStorage("testing");
 }
 
 var tests = [
   function () { return testingStorage().addNamed(createRandomBlob(), gFileName); },
   function () { return testingStorage().delete(gFileName); },
   function () { return testingStorage().get(gFileName); },
   function () { var r = testingStorage().enumerate("../"); return r; }
 ];
--- a/dom/devicestorage/test/test_enumerate.html
+++ b/dom/devicestorage/test/test_enumerate.html
@@ -36,32 +36,32 @@ function enumerateSuccess(e) {
   var filename = e.target.result.name;
 
   var index = files.indexOf(filename);
   files.remove(index);
 
   ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
 
   // clean up
-  var cleanup = storage[0].delete(prefix + "/" + filename);
+  var cleanup = storage.delete(prefix + "/" + filename);
   cleanup.onsuccess = function(e) {}  // todo - can i remove this?
 
   e.target.continue();
 }
 
 function handleError(e) {
   ok(false, "handleError was called : " + e.target.error.name);
   devicestorage_cleanup();
 }
 
 function addSuccess(e) {
   addedSoFar = addedSoFar + 1;
   if (addedSoFar == files.length) {
 
-    var cursor = storage[0].enumerate(prefix);
+    var cursor = storage.enumerate(prefix);
     cursor.onsuccess = enumerateSuccess;
     cursor.onerror = handleError;
   }
 }
 
 function addError(e) {
   ok(false, "addError was called : " + e.target.error.name);
   devicestorage_cleanup();
@@ -72,17 +72,17 @@ ok(navigator.getDeviceStorage, "Should h
 var prefix = "devicestorage/" + randomFilename(12)
 
 var files = [ "a", "b", "c", "d/a", "d/b", "d/c", "d/d", "The/quick/brown/fox/jumps/over/the/lazy/dog"]
 var addedSoFar = 0;
 
 
 for (var i=0; i<files.length; i++) {
 
- request = storage[0].addNamed(createRandomBlob(), prefix + '/' + files[i]);
+ request = storage.addNamed(createRandomBlob(), prefix + '/' + files[i]);
 
  ok(request, "Should have a non-null request");
  request.onsuccess = addSuccess;
  request.onerror = addError;
 }
 
 </script>
 </pre>
--- a/dom/devicestorage/test/test_enumerateMultipleContinue.html
+++ b/dom/devicestorage/test/test_enumerateMultipleContinue.html
@@ -25,17 +25,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 devicestorage_setup();
 
 function enumerateSuccess(e) {
 }
 
 function enumerateFailure(e) {
 }
 
-var cursor = navigator.getDeviceStorage("testing")[0].enumerate();
+var cursor = navigator.getDeviceStorage("testing").enumerate();
 cursor.onsuccess = enumerateSuccess;
 cursor.onerror = enumerateFailure;
 
 try {
  cursor.continue();
 }
 catch (e) {
   ok(true, "Calling continue before enumerateSuccess fires should throw");
--- a/dom/devicestorage/test/test_enumerateNoParam.html
+++ b/dom/devicestorage/test/test_enumerateNoParam.html
@@ -40,32 +40,32 @@ function enumerateSuccess(e) {
   
   var filename = e.target.result.name;
   var index = files.indexOf(filename);
   files.remove(index);
 
   ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
 
   // clean up
-  var cleanup = storage[0].delete(prefix + "/" + filename);
+  var cleanup = storage.delete(prefix + "/" + filename);
   cleanup.onsuccess = function(e) {}  // todo - can i remove this?
 
   e.target.continue();
 }
 
 function handleError(e) {
   ok(false, "handleError was called : " + e.target.error.name);
   devicestorage_cleanup();
 }
 
 function addSuccess(e) {
   addedSoFar = addedSoFar + 1;
   if (addedSoFar == files.length) {
 
-    var cursor = storage[0].enumerate();
+    var cursor = storage.enumerate();
     cursor.onsuccess = enumerateSuccess;
     cursor.onerror = handleError;
   }
 }
 
 function addError(e) {
   ok(false, "addError was called : " + e.target.error.name);
   devicestorage_cleanup();
@@ -76,17 +76,17 @@ ok(navigator.getDeviceStorage, "Should h
 var prefix = "devicestorage/" + randomFilename(12)
 
 var files = [ "a", "b", "c" ]
 var addedSoFar = 0;
 
 
 for (var i=0; i<files.length; i++) {
 
- request = storage[0].addNamed(createRandomBlob(), prefix + '/' + files[i]);
+ request = storage.addNamed(createRandomBlob(), prefix + '/' + files[i]);
 
  ok(request, "Should have a non-null request");
  request.onsuccess = addSuccess;
  request.onerror = addError;
 }
 
 </script>
 </pre>
--- a/dom/devicestorage/test/test_enumerateOptions.html
+++ b/dom/devicestorage/test/test_enumerateOptions.html
@@ -25,53 +25,53 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 devicestorage_setup()
 
 storage = navigator.getDeviceStorage("testing");
 
 
 throws = false;
 try {
-var cursor = storage[0].enumerate();
+var cursor = storage.enumerate();
 } catch(e) {throws = true}
 ok(!throws, "enumerate no parameter");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate("string");
+var cursor = storage.enumerate("string");
 } catch(e) {throws = true}
 ok(!throws, "enumerate one string parameter");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate("string", "string2");
+var cursor = storage.enumerate("string", "string2");
 } catch(e) {throws = true}
 ok(throws, "enumerate two string parameter");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate("string", {"since": 1});
+var cursor = storage.enumerate("string", {"since": 1});
 } catch(e) {throws = true}
 ok(!throws, "enumerate a string and object parameter");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate({"path": "a"});
+var cursor = storage.enumerate({"path": "a"});
 } catch(e) {throws = true}
 ok(!throws, "enumerate object parameter with path");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate({}, "string");
+var cursor = storage.enumerate({}, "string");
 } catch(e) {throws = true}
 ok(throws, "enumerate object then a string");
 
 throws = false;
 try {
-var cursor = storage[0].enumerate({"path": "a", "since": 0});
+var cursor = storage.enumerate({"path": "a", "since": 0});
 } catch(e) {throws = true}
 ok(!throws, "enumerate object parameter with path");
 
 
 
 
 devicestorage_cleanup()
 </script>
--- a/dom/devicestorage/test/test_lastModificationFilter.html
+++ b/dom/devicestorage/test/test_lastModificationFilter.html
@@ -40,17 +40,17 @@ function verifyAndDelete(prefix, files, 
   ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
   if (index == -1)
     return;
 
   files.remove(index);
 
   // clean up
   var storage = navigator.getDeviceStorage("testing");
-  var cleanup = storage[0].delete(prefix + "/" + filename);
+  var cleanup = storage.delete(prefix + "/" + filename);
   cleanup.onsuccess = function(e) {}
 }
 
 function addFiles(prefix, files, date, callback) {
 
   const Cc = SpecialPowers.wrap(Components).classes;
   const Ci = Components.interfaces;
 
@@ -83,17 +83,17 @@ var newFiles = ["d", "e", "f"];
 addFiles(prefix, oldFiles, 157795200, addNewFiles);
 
 function enumerateNew() {
 
   var storage = navigator.getDeviceStorage("testing");
   ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
 
 // 836031600 is a long time ago
-  var cursor = storage[0].enumerate(prefix, {"since": new Date(836031600)});
+  var cursor = storage.enumerate(prefix, {"since": new Date(836031600)});
   cursor.onsuccess = function(e) {
     verifyAndDelete(prefix, newFiles, e);
     if (e.target.result) {
       e.target.continue();
     }
   }
 
   cursor.onerror = function (e) {
--- a/dom/devicestorage/test/test_overwrite.html
+++ b/dom/devicestorage/test/test_overwrite.html
@@ -41,46 +41,46 @@ function addOverwritingSuccess(e) {
   ok(false, "addOverwritingSuccess was called.");
   devicestorage_cleanup();
 }
 
 function addOverwritingError(e) {
   ok(true, "Adding to the same location should fail");
 
   var storage = navigator.getDeviceStorage("testing");
-  request = storage[0].delete(filename)
+  request = storage.delete(filename)
   request.onsuccess = deleteSuccess;
   request.onerror = deleteError;
 }
 
 function addSuccess(e) {
   ok(true, "addSuccess was called");
 
   var storage = navigator.getDeviceStorage("testing");
   ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
 
-  request = storage[0].addNamed(createRandomBlob(), filename);
+  request = storage.addNamed(createRandomBlob(), filename);
   ok(request, "Should have a non-null request");
 
   request.onsuccess = addOverwritingSuccess;
   request.onerror = addOverwritingError;
 }
 
 function addError(e) {
   // test file is already exists.  clean it up and try again..
   var storage = navigator.getDeviceStorage("testing");
-  request = storage[0].delete(filename)
+  request = storage.delete(filename)
   request.onsuccess = runtest;
 }
 
 function runtest() {
   var storage = navigator.getDeviceStorage("testing");
   ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
 
-  request = storage[0].addNamed(createRandomBlob(), filename);
+  request = storage.addNamed(createRandomBlob(), filename);
   ok(request, "Should have a non-null request");
 
   request.onsuccess = addSuccess;
   request.onerror = addError;
 }
 
 runtest();
 
--- a/dom/devicestorage/test/test_sanity.html
+++ b/dom/devicestorage/test/test_sanity.html
@@ -36,17 +36,17 @@ try {
 ok(throws, "getDeviceStorage takes one arg");
 
 storage = navigator.getDeviceStorage("kilimanjaro");
 ok(!storage, "kilimanjaro - Should not have this type of storage");
 
 storage = navigator.getDeviceStorage("testing");
 ok(storage, "testing - Should have getDeviceStorage");
 
-var cursor = storage[0].enumerate();
+var cursor = storage.enumerate();
 ok(cursor, "Should have a non-null cursor");
 
 devicestorage_cleanup();
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/interfaces/devicestorage/nsIDOMNavigatorDeviceStorage.idl
+++ b/dom/interfaces/devicestorage/nsIDOMNavigatorDeviceStorage.idl
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
-interface nsIVariant;
+interface nsIDOMDeviceStorage;
 
 /**
  * Property that extends the navigator object.
  */
-[scriptable, uuid(A4B2831D-6065-472F-8A6D-2C9085C74C15)]
+[scriptable, uuid(da1fbf6e-259c-40bc-ba8c-4ae81748dca3)]
 interface nsIDOMNavigatorDeviceStorage : nsISupports
 {
-    // returns an array of nsIDOMDeviceStorage
-    nsIVariant getDeviceStorage(in DOMString type);
+  nsIDOMDeviceStorage getDeviceStorage(in DOMString type);
 };
-