Bug 991766 - Webapp uninstallation on Mac through mozapps uninstall function. r=myk, r=smichaud
☠☠ backed out by 93caa1abf5a3 ☠ ☠
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Sun, 13 Apr 2014 16:17:51 -0400
changeset 178294 d0012e4d8a9a4cd0dd99bd0afd76541f7fecb870
parent 178293 d0874032eebac33f4e495cec2da7ed60ed08fe39
child 178295 d1e74ffe92acb8c2ce42ed949b4cc5552b629423
push id26580
push usercbook@mozilla.com
push dateMon, 14 Apr 2014 13:20:46 +0000
treeherdermozilla-central@9b2c4a85a5e1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmyk, smichaud
bugs991766
milestone31.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 991766 - Webapp uninstallation on Mac through mozapps uninstall function. r=myk, r=smichaud
toolkit/webapps/WebappOSUtils.jsm
widget/cocoa/nsMacWebAppUtils.mm
widget/nsIMacWebAppUtils.idl
--- a/toolkit/webapps/WebappOSUtils.jsm
+++ b/toolkit/webapps/WebappOSUtils.jsm
@@ -1,16 +1,13 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const CC = Components.Constructor;
-const Cu = Components.utils;
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 
 this.EXPORTED_SYMBOLS = ["WebappOSUtils"];
 
@@ -114,18 +111,18 @@ this.WebappOSUtils = {
                           "nsILocalFile", "initWithPath");
     let launchTarget = initWithPath(installLocation);
     launchTarget.append(appFilename + ".exe");
 
     return launchTarget;
 #elifdef XP_MACOSX
     let uniqueName = this.getUniqueName(aApp);
 
-    let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"]
-                     .createInstance(Ci.nsIMacWebAppUtils);
+    let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"].
+                   createInstance(Ci.nsIMacWebAppUtils);
 
     try {
       let path;
       if (path = mwaUtils.pathForAppWithIdentifier(uniqueName)) {
         return [ uniqueName, path ];
       }
     } catch(ex) {}
 
@@ -260,18 +257,18 @@ this.WebappOSUtils = {
 
     return true;
 #elifdef XP_MACOSX
     let [ launchIdentifier, path ] = this.getLaunchTarget(aApp);
     if (!launchIdentifier) {
       return false;
     }
 
-    let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"]
-                     .createInstance(Ci.nsIMacWebAppUtils);
+    let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"].
+                   createInstance(Ci.nsIMacWebAppUtils);
 
     try {
       mwaUtils.launchAppWithIdentifier(launchIdentifier);
     } catch(e) {
       return false;
     }
 
     return true;
@@ -326,17 +323,35 @@ this.WebappOSUtils = {
     } catch (e) {
       deferred.reject(e);
     } finally {
       appRegKey.value.close();
     }
 
     return deferred.promise;
 #elifdef XP_MACOSX
-    return Promise.reject("Uninstallation not yet implemented");
+    let [ , path ] = this.getLaunchTarget(aApp);
+    if (!path) {
+      return Promise.reject("App not found");
+    }
+
+    let deferred = Promise.defer();
+
+    let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"].
+                   createInstance(Ci.nsIMacWebAppUtils);
+
+    mwaUtils.trashApp(path, (aResult) => {
+      if (aResult == Cr.NS_OK) {
+        deferred.resolve(true);
+      } else {
+        deferred.resolve("Error moving the app to the Trash: " + aResult);
+      }
+    });
+
+    return deferred.promise;
 #elifdef XP_UNIX
     let exeFile = this.getLaunchTarget(aApp);
     if (!exeFile) {
       return Promise.reject("App executable file not found");
     }
 
     let deferred = Promise.defer();
 
--- a/widget/cocoa/nsMacWebAppUtils.mm
+++ b/widget/cocoa/nsMacWebAppUtils.mm
@@ -52,8 +52,31 @@ NS_IMETHODIMP nsMacWebAppUtils::LaunchAp
                         options: (NSWorkspaceLaunchOptions)0
                         additionalEventParamDescriptor: nil
                         launchIdentifier: NULL];
 
   return success ? NS_OK : NS_ERROR_FAILURE;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
+
+NS_IMETHODIMP nsMacWebAppUtils::TrashApp(const nsAString& path, nsITrashAppCallback* aCallback) {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  if (NS_WARN_IF(!aCallback)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsCOMPtr<nsITrashAppCallback> callback = aCallback;
+
+  NSString* tempString = [NSString stringWithCharacters:reinterpret_cast<const unichar*>(((nsString)path).get())
+                                   length:path.Length()];
+
+  [[NSWorkspace sharedWorkspace] recycleURLs: [NSArray arrayWithObject:[NSURL fileURLWithPath:tempString]]
+    completionHandler: ^(NSDictionary *newURLs, NSError *error) {
+      nsresult rv = (error == nil) ? NS_OK : NS_ERROR_FAILURE;
+      callback->TrashAppFinished(rv);
+    }];
+
+  return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
--- a/widget/nsIMacWebAppUtils.idl
+++ b/widget/nsIMacWebAppUtils.idl
@@ -1,25 +1,35 @@
 /* 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 "nsISupports.idl"
 
 interface nsIMacWebAppUtils;
 
+[scriptable, function, uuid(8c899c4f-58c1-4b74-9034-3bb64e484b68)]
+interface nsITrashAppCallback : nsISupports
+{
+  void trashAppFinished(in nsresult rv);
+};
+
 /**
  * Allow MozApps API to locate and manipulate natively installed apps
  */
 
-[scriptable, uuid(e9096367-ddd9-45e4-b762-49c0c18b7119)]
+[scriptable, uuid(c69cf343-ea41-428b-b161-4655fd54d8e7)]
 interface nsIMacWebAppUtils : nsISupports {
   /**
    * Find the path for an app with the given signature.
    */
   AString pathForAppWithIdentifier(in AString bundleIdentifier);
 
   /**
    * Launch the app with the given identifier, if it exists.
    */
   void launchAppWithIdentifier(in AString bundleIdentifier);
 
+  /**
+   * Move the app from the given directory to the Trash.
+   */
+  void trashApp(in AString path, in nsITrashAppCallback callback);
 };