Bug 777084 - Stop returning arrays from DeviceStorage.getDeviceStorage(). r=sicking
authorDoug Turner <dougt@dougt.org>
Wed, 01 Aug 2012 23:32:11 -0700
changeset 101209 cb017d0510296e4f873855f4c9ab09129a64a578
parent 101208 d628a6d43f6c00a9b0d5eae5bda4cbf4addce109
child 101210 074fb996dfd77c993b1de2f91070f4db78714a34
child 101214 865a6f2d3a831e77a6756780acd1d3dbc501bdfa
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssicking
bugs777084
milestone17.0a1
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);
 };
-