Bug 991766 - Webapp uninstallation on Mac through mozapps uninstall function. r=myk, r=smichaud
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Thu, 17 Apr 2014 16:54:50 -0400
changeset 179504 05d9e797718231ff9bb7492447845de8a37dcab5
parent 179503 2bea886b9aac17ba62e22989b6dfb76b60f9f0d0
child 179505 4ad0b2772d4995dd1b5f5da8089215e1f388a0b3
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersmyk, smichaud
bugs991766
milestone31.0a1
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);
 };