Bug 1515729 - Remove Task.jsm usage from mobile/android. r=snorp
authorMark Banner <standard8@mozilla.com>
Fri, 28 Dec 2018 22:36:18 +0000
changeset 512104 9297836c0b83a03b9c645c899621b0d3af4876d3
parent 512103 2dc4dd76f57a6dee78d33c92f45599fcc57db27d
child 512105 f6790e7386ace4aa111adf2f50bcfd4b2a9eb7e8
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1515729
milestone66.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 1515729 - Remove Task.jsm usage from mobile/android. r=snorp Differential Revision: https://phabricator.services.mozilla.com/D15464
mobile/android/chrome/content/Reader.js
mobile/android/chrome/content/browser.js
mobile/android/components/HelperAppDialog.js
mobile/android/components/SessionStore.js
mobile/android/modules/HomeProvider.jsm
mobile/android/modules/Sanitizer.jsm
mobile/android/modules/WebsiteMetadata.jsm
--- a/mobile/android/chrome/content/Reader.js
+++ b/mobile/android/chrome/content/Reader.js
@@ -218,34 +218,34 @@ var Reader = {
   /**
    * Gets an article for a given URL. This method will download and parse a document
    * if it does not find the article in the cache.
    *
    * @param url The article URL.
    * @return {Promise}
    * @resolves JS object representing the article, or null if no article is found.
    */
-  _getArticle: Task.async(function* (url) {
+  async _getArticle(url) {
     // First try to find a parsed article in the cache.
-    let article = yield ReaderMode.getArticleFromCache(url);
+    let article = await ReaderMode.getArticleFromCache(url);
     if (article) {
       return article;
     }
 
     // Article hasn't been found in the cache, we need to
     // download the page and parse the article out of it.
-    return yield ReaderMode.downloadAndParseDocument(url).catch(e => {
+    return ReaderMode.downloadAndParseDocument(url).catch(e => {
       if (e && e.newURL) {
         // Pass up the error so we can navigate the browser in question to the new URL:
         throw e;
       }
       Cu.reportError("Error downloading and parsing document: " + e);
       return null;
     });
-  }),
+  },
 
   _getArticleData: function(browser) {
     return new Promise((resolve, reject) => {
       if (browser == null) {
         reject("_getArticleData needs valid browser");
       }
 
       let mm = browser.messageManager;
@@ -257,31 +257,31 @@ var Reader = {
       mm.sendAsyncMessage("Reader:GetStoredArticleData");
     });
   },
 
 
   /**
    * Migrates old indexedDB reader mode cache to new JSON cache.
    */
-  migrateCache: Task.async(function* () {
-    let cacheDB = yield new Promise((resolve, reject) => {
+  async migrateCache() {
+    let cacheDB = await new Promise((resolve, reject) => {
       let request = window.indexedDB.open("about:reader", 1);
       request.onsuccess = event => resolve(event.target.result);
       request.onerror = event => reject(request.error);
 
       // If there is no DB to migrate, don't do anything.
       request.onupgradeneeded = event => resolve(null);
     });
 
     if (!cacheDB) {
       return;
     }
 
-    let articles = yield new Promise((resolve, reject) => {
+    let articles = await new Promise((resolve, reject) => {
       let articles = [];
 
       let transaction = cacheDB.transaction(cacheDB.objectStoreNames);
       let store = transaction.objectStore(cacheDB.objectStoreNames[0]);
 
       let request = store.openCursor();
       request.onsuccess = event => {
         let cursor = event.target.result;
@@ -291,15 +291,15 @@ var Reader = {
           articles.push(cursor.value);
           cursor.continue();
         }
       };
       request.onerror = event => reject(request.error);
     });
 
     for (let article of articles) {
-      yield ReaderMode.storeArticleInCache(article);
+      await ReaderMode.storeArticleInCache(article);
     }
 
     // Delete the database.
     window.indexedDB.deleteDatabase("about:reader");
-  }),
+  },
 };
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -34,17 +34,16 @@ ChromeUtils.defineModuleGetter(this, "Pl
                                "resource://gre/modules/PluralForm.jsm");
 
 ChromeUtils.defineModuleGetter(this, "Downloads",
                                "resource://gre/modules/Downloads.jsm");
 
 ChromeUtils.defineModuleGetter(this, "UserAgentOverrides",
                                "resource://gre/modules/UserAgentOverrides.jsm");
 
-ChromeUtils.defineModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
 ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 
 ChromeUtils.defineModuleGetter(this, "SafeBrowsing",
                                "resource://gre/modules/SafeBrowsing.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
 
@@ -484,21 +483,21 @@ var BrowserApp = {
           AccessFu.enable();
         } else {
           AccessFu.disable();
         }
       }, "GeckoView:AccessibilitySettings");
     }
 
     InitLater(() => {
-      Task.spawn(function* () {
-        let downloadsDir = yield Downloads.getPreferredDownloadsDirectory();
+      (async () => {
+        let downloadsDir = await Downloads.getPreferredDownloadsDirectory();
         let logsDir = OS.Path.join(downloadsDir, "memory-reports");
-        yield OS.File.removeDir(logsDir);
-      });
+        await OS.File.removeDir(logsDir);
+      })();
     });
 
     // Don't delay loading content.js because when we restore reader mode tabs,
     // we require the reader mode scripts in content.js right away.
     let mm = window.getGroupMessageManager("browsers");
     mm.loadFrameScript("chrome://browser/content/content.js", true, true);
 
     // Listen to manifest messages
@@ -1501,39 +1500,39 @@ var BrowserApp = {
   },
 
   saveAsPDF: function saveAsPDF(aBrowser) {
     RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE).then(function(permissionGranted) {
       if (!permissionGranted) {
         return;
       }
 
-      Task.spawn(function* () {
+      (async () => {
         let fileName = ContentAreaUtils.getDefaultFileName(aBrowser.contentTitle, aBrowser.currentURI, null, null);
         fileName = fileName.trim() + ".pdf";
 
-        let downloadsDir = yield Downloads.getPreferredDownloadsDirectory();
+        let downloadsDir = await Downloads.getPreferredDownloadsDirectory();
         let file = OS.Path.join(downloadsDir, fileName);
 
         // Force this to have a unique name.
-        let openedFile = yield OS.File.openUnique(file, { humanReadable: true });
+        let openedFile = await OS.File.openUnique(file, { humanReadable: true });
         file = openedFile.path;
-        yield openedFile.file.close();
-
-        let download = yield Downloads.createDownload({
+        await openedFile.file.close();
+
+        let download = await Downloads.createDownload({
           source: aBrowser.contentWindow,
           target: file,
           saver: "pdf",
           startTime: Date.now(),
         });
 
-        let list = yield Downloads.getList(download.source.isPrivate ? Downloads.PRIVATE : Downloads.PUBLIC)
-        yield list.add(download);
-        yield download.start();
-      });
+        let list = await Downloads.getList(download.source.isPrivate ? Downloads.PRIVATE : Downloads.PUBLIC);
+        await list.add(download);
+        await download.start();
+      })();
     });
   },
 
   // These values come from pref_tracking_protection_entries in arrays.xml.
   PREF_TRACKING_PROTECTION_ENABLED: "2",
   PREF_TRACKING_PROTECTION_ENABLED_PB: "1",
   PREF_TRACKING_PROTECTION_DISABLED: "0",
 
@@ -6632,61 +6631,64 @@ var Distribution = {
     }
 
     GlobalEventDispatcher.sendRequest({ type: "Distribution:Set:OK" });
   },
 
   // aFile is an nsIFile
   // aCallback takes the parsed JSON object as a parameter
   readJSON: function dc_readJSON(aFile, aCallback) {
-    Task.spawn(function*() {
-      let bytes = yield OS.File.read(aFile.path);
-      let raw = new TextDecoder().decode(bytes) || "";
+    (async () => {
+      try {
+        let bytes = await OS.File.read(aFile.path);
+        let raw = new TextDecoder().decode(bytes) || "";
+      } catch (e) {
+        if (!(e instanceof OS.File.Error && reason.becauseNoSuchFile)) {
+          Cu.reportError("Distribution: Could not read from " + aFile.leafName + " file");
+        }
+        return;
+      }
 
       try {
         aCallback(JSON.parse(raw));
       } catch (e) {
         Cu.reportError("Distribution: Could not parse JSON: " + e);
       }
-    }).catch(function onError(reason) {
-      if (!(reason instanceof OS.File.Error && reason.becauseNoSuchFile)) {
-        Cu.reportError("Distribution: Could not read from " + aFile.leafName + " file");
-      }
-    });
+    })();
   },
 
   // Track pending installs so we can avoid showing notifications for them.
   pendingAddonInstalls: new Set(),
 
-  installDistroAddons: Task.async(function* () {
+  async installDistroAddons() {
     const PREF_ADDONS_INSTALLED = "distribution.addonsInstalled";
     try {
       let installed = Services.prefs.getBoolPref(PREF_ADDONS_INSTALLED);
       if (installed) {
         return;
       }
     } catch (e) {
       Services.prefs.setBoolPref(PREF_ADDONS_INSTALLED, true);
     }
 
     let distroPath;
     try {
       distroPath = FileUtils.getDir("XREAppDist", ["extensions"]).path;
 
-      let info = yield OS.File.stat(distroPath);
+      let info = await OS.File.stat(distroPath);
       if (!info.isDir) {
         return;
       }
     } catch (e) {
       return;
     }
 
     let it = new OS.File.DirectoryIterator(distroPath);
     try {
-      yield it.forEach(entry => {
+      await it.forEach(entry => {
         // Only support extensions that are zipped in .xpi files.
         if (entry.isDir || !entry.name.endsWith(".xpi")) {
           dump("Ignoring distribution add-on that isn't an XPI: " + entry.path);
           return;
         }
 
         AddonManager.getInstallForFile(new FileUtils.File(entry.path), null,
                                        {source: "distribution"}).then(install => {
@@ -6699,17 +6701,17 @@ var Distribution = {
           install.install();
         }).catch(e => {
           Cu.reportError("Error installing distribution add-on: " + entry.path + ": " + e);
         });
       });
     } finally {
       it.close();
     }
-  })
+  },
 };
 
 var Tabs = {
   _enableTabExpiration: false,
   _useCache: false,
   _domains: new Set(),
 
   init: function() {
--- a/mobile/android/components/HelperAppDialog.js
+++ b/mobile/android/components/HelperAppDialog.js
@@ -21,17 +21,16 @@ XPCOMUtils.defineLazyModuleGetters(this,
   Downloads: "resource://gre/modules/Downloads.jsm",
   EventDispatcher: "resource://gre/modules/Messaging.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   HelperApps: "resource://gre/modules/HelperApps.jsm",
   NetUtil: "resource://gre/modules/NetUtil.jsm",
   RuntimePermissions: "resource://gre/modules/RuntimePermissions.jsm",
   Services: "resource://gre/modules/Services.jsm",
   Snackbars: "resource://gre/modules/Snackbars.jsm",
-  Task: "resource://gre/modules/Task.jsm",
 });
 
 // -----------------------------------------------------------------------
 // HelperApp Launcher Dialog
 // -----------------------------------------------------------------------
 
 XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
   let ContentAreaUtils = {};
@@ -131,26 +130,26 @@ HelperAppLauncherDialog.prototype = {
 
   show: function hald_show(aLauncher, aContext, aReason) {
     if (!this._canDownload(aLauncher.source)) {
       this._refuseDownload(aLauncher);
       return;
     }
 
     if (this._shouldForwardToAndroidDownloadManager(aLauncher)) {
-      Task.spawn(function* () {
+      (async () => {
         try {
-          let hasPermission = yield RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
+          let hasPermission = await RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
           if (hasPermission) {
             this._downloadWithAndroidDownloadManager(aLauncher);
           }
         } finally {
           aLauncher.cancel(Cr.NS_BINDING_ABORTED);
         }
-      }.bind(this)).catch(Cu.reportError);
+      })().catch(Cu.reportError);
       return;
     }
 
     let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 
     let apps = HelperApps.getAppsForUri(aLauncher.source, {
       mimeType: aLauncher.MIMEInfo.MIMEType,
     });
@@ -300,33 +299,33 @@ HelperAppLauncherDialog.prototype = {
     if (app)
       Services.prefs.setCharPref(this._getPrefName(mime), app.packageName);
     else
       Services.prefs.clearUserPref(this._getPrefName(mime));
   },
 
   promptForSaveToFileAsync: function(aLauncher, aContext, aDefaultFile,
                                       aSuggestedFileExt, aForcePrompt) {
-    Task.spawn(function* () {
+    (async () => {
       let file = null;
       try {
-        let hasPermission = yield RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
+        let hasPermission = await RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
         if (hasPermission) {
           // If we do have the STORAGE permission then pick the public downloads directory as destination
           // for this file. Without the permission saveDestinationAvailable(null) will be called which
           // will effectively cancel the download.
-          let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
+          let preferredDir = await Downloads.getPreferredDownloadsDirectory();
           file = this.validateLeafName(new FileUtils.File(preferredDir),
                                        aDefaultFile, aSuggestedFileExt);
         }
       } finally {
         // The file argument will be null in case any exception occurred.
         aLauncher.saveDestinationAvailable(file);
       }
-    }.bind(this)).catch(Cu.reportError);
+    })().catch(Cu.reportError);
   },
 
   validateLeafName: function hald_validateLeafName(aLocalFile, aLeafName, aFileExt) {
     if (!(aLocalFile && this.isUsableDirectory(aLocalFile)))
       return null;
 
     // Remove any leading periods, since we don't want to save hidden files
     // automatically.
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -10,17 +10,16 @@ ChromeUtils.import("resource://gre/modul
 XPCOMUtils.defineLazyModuleGetters(this, {
   EventDispatcher: "resource://gre/modules/Messaging.jsm",
   FormData: "resource://gre/modules/FormData.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
   SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
-  Task: "resource://gre/modules/Task.jsm",
   Utils: "resource://gre/modules/sessionstore/Utils.jsm",
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/AndroidLog.jsm", "AndroidLog");
 
 const ssu = Cc["@mozilla.org/browser/sessionstore/utils;1"]
               .getService(Ci.nsISessionStoreUtils);
 
@@ -1629,28 +1628,28 @@ SessionStore.prototype = {
   deleteTabValue: function ss_deleteTabValue(aTab, aKey) {
     let browser = aTab.browser;
     if (browser.__SS_extdata && aKey in browser.__SS_extdata) {
       delete browser.__SS_extdata[aKey];
       this.saveStateDelayed();
     }
   },
 
-  restoreLastSession: Task.async(function* (aSessionString) {
+  restoreLastSession(aSessionString) {
     let notifyMessage = "";
 
     try {
       this._restoreWindow(aSessionString);
     } catch (e) {
       Cu.reportError("SessionStore: " + e);
       notifyMessage = "fail";
     }
 
     Services.obs.notifyObservers(null, "sessionstore-windows-restored", notifyMessage);
-  }),
+  },
 
   removeWindow: function ss_removeWindow(aWindow) {
     if (!aWindow || !aWindow.__SSID || !this._windows[aWindow.__SSID]) {
       return;
     }
 
     delete this._windows[aWindow.__SSID];
     delete aWindow.__SSID;
--- a/mobile/android/modules/HomeProvider.jsm
+++ b/mobile/android/modules/HomeProvider.jsm
@@ -6,17 +6,16 @@
 "use strict";
 
 var EXPORTED_SYMBOLS = [ "HomeProvider" ];
 
 ChromeUtils.import("resource://gre/modules/Messaging.jsm");
 ChromeUtils.import("resource://gre/modules/osfile.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/Sqlite.jsm");
-ChromeUtils.import("resource://gre/modules/Task.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 /*
  * SCHEMA_VERSION history:
  *   1: Create HomeProvider (bug 942288)
  *   2: Add filter column to items table (bug 942295/975841)
  *   3: Add background_color and background_url columns (bug 1157539)
  */
@@ -202,82 +201,76 @@ var HomeProvider = Object.freeze({
 });
 
 var gDatabaseEnsured = false;
 
 /**
  * Creates the database schema.
  */
 function createDatabase(db) {
-  return Task.spawn(function* create_database_task() {
-    yield db.execute(SQL.createItemsTable);
-  });
+  return db.execute(SQL.createItemsTable);
 }
 
 /**
  * Migrates the database schema to a new version.
  */
-function upgradeDatabase(db, oldVersion, newVersion) {
-  return Task.spawn(function* upgrade_database_task() {
-    switch (oldVersion) {
-      case 1:
-        // Migration from v1 to latest:
-        // Recreate the items table discarding any
-        // existing data.
-        yield db.execute(SQL.dropItemsTable);
-        yield db.execute(SQL.createItemsTable);
-        break;
+async function upgradeDatabase(db, oldVersion, newVersion) {
+  switch (oldVersion) {
+    case 1:
+      // Migration from v1 to latest:
+      // Recreate the items table discarding any
+      // existing data.
+      await db.execute(SQL.dropItemsTable);
+      await db.execute(SQL.createItemsTable);
+      break;
 
-      case 2:
-        // Migration from v2 to latest:
-        // Add new columns: background_color, background_url
-        yield db.execute(SQL.addColumnBackgroundColor);
-        yield db.execute(SQL.addColumnBackgroundUrl);
-        break;
-    }
-  });
+    case 2:
+      // Migration from v2 to latest:
+      // Add new columns: background_color, background_url
+      await db.execute(SQL.addColumnBackgroundColor);
+      await db.execute(SQL.addColumnBackgroundUrl);
+      break;
+  }
 }
 
 /**
  * Opens a database connection and makes sure that the database schema version
  * is correct, performing migrations if necessary. Consumers should be sure
  * to close any database connections they open.
  *
  * @return Promise
  * @resolves Handle on an opened SQLite database.
  */
-function getDatabaseConnection() {
-  return Task.spawn(function* get_database_connection_task() {
-    let db = yield Sqlite.openConnection({ path: DB_PATH });
-    if (gDatabaseEnsured) {
-      return db;
+async function getDatabaseConnection() {
+  let db = await Sqlite.openConnection({ path: DB_PATH });
+  if (gDatabaseEnsured) {
+    return db;
+  }
+
+  try {
+    // Check to see if we need to perform any migrations.
+    let dbVersion = parseInt(await db.getSchemaVersion());
+
+    // getSchemaVersion() returns a 0 int if the schema
+    // version is undefined.
+    if (dbVersion === 0) {
+      await createDatabase(db);
+    } else if (dbVersion < SCHEMA_VERSION) {
+      await upgradeDatabase(db, dbVersion, SCHEMA_VERSION);
     }
 
-    try {
-      // Check to see if we need to perform any migrations.
-      let dbVersion = parseInt(yield db.getSchemaVersion());
+    await db.setSchemaVersion(SCHEMA_VERSION);
+  } catch (e) {
+    // Close the DB connection before passing the exception to the consumer.
+    await db.close();
+    throw e;
+  }
 
-      // getSchemaVersion() returns a 0 int if the schema
-      // version is undefined.
-      if (dbVersion === 0) {
-        yield createDatabase(db);
-      } else if (dbVersion < SCHEMA_VERSION) {
-        yield upgradeDatabase(db, dbVersion, SCHEMA_VERSION);
-      }
-
-      yield db.setSchemaVersion(SCHEMA_VERSION);
-    } catch (e) {
-      // Close the DB connection before passing the exception to the consumer.
-      yield db.close();
-      throw e;
-    }
-
-    gDatabaseEnsured = true;
-    return db;
-  });
+  gDatabaseEnsured = true;
+  return db;
 }
 
 /**
  * Validates an item to be saved to the DB.
  *
  * @param item
  *        (object) item object to be validated.
  */
@@ -333,69 +326,65 @@ HomeStorage.prototype = {
    * @param options
    *        A JS object holding additional cofiguration properties.
    *        The following properties are currently supported:
    *        - replace (boolean): Whether or not to replace existing items.
    *
    * @return Promise
    * @resolves When the operation has completed.
    */
-  save: function(data, options) {
+  async save(data, options) {
     if (data && data.length > MAX_SAVE_COUNT) {
       throw "save failed for dataset = " + this.datasetId +
         ": you cannot save more than " + MAX_SAVE_COUNT + " items at once";
     }
 
-    return Task.spawn(function* save_task() {
-      let db = yield getDatabaseConnection();
-      try {
-        yield db.executeTransaction(function* save_transaction() {
-          if (options && options.replace) {
-            yield db.executeCached(SQL.deleteFromDataset, { dataset_id: this.datasetId });
-          }
+    let db = await getDatabaseConnection();
+    try {
+      await db.executeTransaction(async function save_transaction() {
+        if (options && options.replace) {
+          await db.executeCached(SQL.deleteFromDataset, { dataset_id: this.datasetId });
+        }
 
-          // Insert data into DB.
-          for (let item of data) {
-            validateItem(this.datasetId, item);
+        // Insert data into DB.
+        for (let item of data) {
+          validateItem(this.datasetId, item);
 
-            // XXX: Directly pass item as params? More validation for item?
-            let params = {
-              dataset_id: this.datasetId,
-              url: item.url,
-              title: item.title,
-              description: item.description,
-              image_url: item.image_url,
-              background_color: item.background_color,
-              background_url: item.background_url,
-              filter: item.filter,
-              created: Date.now(),
-            };
-            yield db.executeCached(SQL.insertItem, params);
-          }
-        }.bind(this));
-      } finally {
-        yield db.close();
-      }
+          // XXX: Directly pass item as params? More validation for item?
+          let params = {
+            dataset_id: this.datasetId,
+            url: item.url,
+            title: item.title,
+            description: item.description,
+            image_url: item.image_url,
+            background_color: item.background_color,
+            background_url: item.background_url,
+            filter: item.filter,
+            created: Date.now(),
+          };
+          await db.executeCached(SQL.insertItem, params);
+        }
+      }.bind(this));
+    } finally {
+      await db.close();
+    }
 
-      refreshDataset(this.datasetId);
-    }.bind(this));
+    refreshDataset(this.datasetId);
   },
 
   /**
    * Deletes all rows associated with this storage.
    *
    * @return Promise
    * @resolves When the operation has completed.
    */
-  deleteAll: function() {
-    return Task.spawn(function* delete_all_task() {
-      let db = yield getDatabaseConnection();
-      try {
-        let params = { dataset_id: this.datasetId };
-        yield db.executeCached(SQL.deleteFromDataset, params);
-      } finally {
-        yield db.close();
-      }
+  async deleteAll() {
+    let db = await getDatabaseConnection();
+    try {
+      let params = { dataset_id: this.datasetId };
+      await db.executeCached(SQL.deleteFromDataset, params);
+    } finally {
+      await db.close();
+    }
 
-      refreshDataset(this.datasetId);
-    }.bind(this));
+    refreshDataset(this.datasetId);
   },
 };
--- a/mobile/android/modules/Sanitizer.jsm
+++ b/mobile/android/modules/Sanitizer.jsm
@@ -11,17 +11,16 @@ ChromeUtils.import("resource://gre/modul
 XPCOMUtils.defineLazyModuleGetters(this, {
   Accounts: "resource://gre/modules/Accounts.jsm",
   Downloads: "resource://gre/modules/Downloads.jsm",
   EventDispatcher: "resource://gre/modules/Messaging.jsm",
   FormHistory: "resource://gre/modules/FormHistory.jsm",
   OfflineAppCacheHelper: "resource://gre/modules/offlineAppCache.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
-  Task: "resource://gre/modules/Task.jsm",
 });
 
 XPCOMUtils.defineLazyServiceGetters(this, {
   quotaManagerService: ["@mozilla.org/dom/quota-manager-service;1", "nsIQuotaManagerService"],
 });
 
 /* global DownloadIntegration */
 Integration.downloads.defineModuleGetter(this, "DownloadIntegration",
@@ -138,17 +137,17 @@ Sanitizer.prototype = {
 
       get canClear() {
         return true;
       },
     },
 
     // Same as desktop Firefox.
     siteSettings: {
-      clear: Task.async(function* () {
+      async clear() {
         let refObj = {};
         TelemetryStopwatch.start("FX_SANITIZE_SITESETTINGS", refObj);
 
         // Clear site-specific permissions like "Allow this site to open popups"
         Services.perms.removeAll();
 
         // Clear site-specific settings like page-zoom level
         Cc["@mozilla.org/content-pref/service;1"]
@@ -156,30 +155,30 @@ Sanitizer.prototype = {
           .removeAllDomains(null);
 
         // Clear site security settings
         var sss = Cc["@mozilla.org/ssservice;1"]
                     .getService(Ci.nsISiteSecurityService);
         sss.clearAll();
 
         // Clear push subscriptions
-        yield new Promise((resolve, reject) => {
+        await new Promise((resolve, reject) => {
           let push = Cc["@mozilla.org/push/Service;1"]
                        .getService(Ci.nsIPushService);
           push.clearForDomain("*", status => {
             if (Components.isSuccessCode(status)) {
               resolve();
             } else {
               reject(new Error("Error clearing push subscriptions: " +
                                status));
             }
           });
         });
         TelemetryStopwatch.finish("FX_SANITIZE_SITESETTINGS", refObj);
-      }),
+      },
 
       get canClear() {
         return true;
       },
     },
 
     // Same as desktop Firefox.
     offlineApps: {
@@ -321,37 +320,39 @@ Sanitizer.prototype = {
           handleCompletion: function(aReason) { aCallback(aReason == 0 && count > 0); },
         };
         FormHistory.count({}, countDone);
       },
     },
 
     // Adapted from desktop, but heavily modified - see comments below.
     downloadFiles: {
-      clear: Task.async(function* ({ startTime = 0,
-                                     deleteFiles = true,
-                                     clearUnfinishedDownloads = false } = {}) {
+      async clear({
+        startTime = 0,
+        deleteFiles = true,
+        clearUnfinishedDownloads = false,
+      } = {}) {
         let refObj = {};
         TelemetryStopwatch.start("FX_SANITIZE_DOWNLOADS", refObj);
 
-        let list = yield Downloads.getList(Downloads.ALL);
-        let downloads = yield list.getAll();
+        let list = await Downloads.getList(Downloads.ALL);
+        let downloads = await list.getAll();
         var finalizePromises = [];
 
         // Logic copied from DownloadList.removeFinished. Ideally, we would
         // just use that method directly, but we want to be able to remove the
         // downloaded files as well.
         for (let download of downloads) {
           let downloadFinished = download.stopped &&
                                  (!download.hasPartialData || download.error);
           if ((downloadFinished || clearUnfinishedDownloads) &&
                download.startTime.getTime() >= startTime) {
             // Remove the download first, so that the views don't get the change
             // notifications that may occur during finalization.
-            yield list.remove(download);
+            await list.remove(download);
             // Ensure that the download is stopped and no partial data is kept.
             // This works even if the download state has changed meanwhile.  We
             // don't need to wait for the procedure to be complete before
             // processing the other downloads in the list.
             finalizePromises.push(download.finalize(true).then(() => null, Cu.reportError));
 
             if (deleteFiles) {
               // Delete the downloaded files themselves.
@@ -359,20 +360,20 @@ Sanitizer.prototype = {
                 if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) {
                   Cu.reportError(ex);
                 }
               });
             }
           }
         }
 
-        yield Promise.all(finalizePromises);
-        yield DownloadIntegration.forceSave();
+        await Promise.all(finalizePromises);
+        await DownloadIntegration.forceSave();
         TelemetryStopwatch.finish("FX_SANITIZE_DOWNLOADS", refObj);
-      }),
+      },
 
       get canClear() {
         return true;
       },
     },
 
     // Specific to Fennec.
     passwords: {
--- a/mobile/android/modules/WebsiteMetadata.jsm
+++ b/mobile/android/modules/WebsiteMetadata.jsm
@@ -1,48 +1,43 @@
 /* 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/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["WebsiteMetadata"];
 
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
 ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm");
-ChromeUtils.defineModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
 
 var WebsiteMetadata = {
   /**
    * Asynchronously parse the document extract metadata. A 'Website:Metadata' event with the metadata
    * will be sent.
    */
   parseAsynchronously: function(doc) {
-    Task.spawn(function() {
-      let metadata = getMetadata(doc, doc.location.href, {
-        image_url: metadataRules.image_url,
-        provider: metadataRules.provider,
-        description_length: metadataRules.description_length,
-      });
+    let metadata = getMetadata(doc, doc.location.href, {
+      image_url: metadataRules.image_url,
+      provider: metadataRules.provider,
+      description_length: metadataRules.description_length,
+    });
 
-      // No metadata was extracted, so don't bother sending it.
-      if (Object.keys(metadata).length === 0) {
-        return;
-      }
+    // No metadata was extracted, so don't bother sending it.
+    if (Object.keys(metadata).length === 0) {
+      return;
+    }
 
-      let msg = {
-        type: "Website:Metadata",
-        location: doc.location.href,
-        hasImage: metadata.image_url && metadata.image_url !== "",
-        metadata: JSON.stringify(metadata),
-      };
+    let msg = {
+      type: "Website:Metadata",
+      location: doc.location.href,
+      hasImage: metadata.image_url && metadata.image_url !== "",
+      metadata: JSON.stringify(metadata),
+    };
 
-      EventDispatcher.instance.sendRequest(msg);
-    });
+    EventDispatcher.instance.sendRequest(msg);
   },
 };
 
 // #################################################################################################
 // # Modified version of makeUrlAbsolute() to not import url parser library (and dependencies)
 // #################################################################################################
 
 function makeUrlAbsolute(context, relative) {