[gnome-shell] extensionSystem: Add "UninstallExtension" DBus method



commit 7928f90cf6e13a20f8dca6a0d413d4c8070acdf8
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Sep 10 17:10:50 2011 -0400

    extensionSystem: Add "UninstallExtension" DBus method
    
    For those who like their system pure, this provides the ability to purge a
    pesky extension and its precious place on your disk space, and in your
    "Local Extension" list.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=658612
    
    Conflicts:
    
    	js/ui/extensionSystem.js

 js/misc/fileUtils.js     |   22 ++++++++++++++++++++++
 js/ui/extensionSystem.js |   32 ++++++++++++++++++++++++++++++++
 js/ui/shellDBus.js       |    8 ++++++++
 3 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/js/misc/fileUtils.js b/js/misc/fileUtils.js
index 4110041..ea80dc3 100644
--- a/js/misc/fileUtils.js
+++ b/js/misc/fileUtils.js
@@ -20,3 +20,25 @@ function listDirAsync(file, callback) {
         enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
     });
 }
+
+function deleteGFile(file) {
+    // Work around 'delete' being a keyword in JS.
+    return file['delete'](null);
+}
+
+function recursivelyDeleteDir(dir) {
+    let children = dir.enumerate_children('standard::name,standard::type',
+                                          Gio.FileQueryInfoFlags.NONE, null);
+
+    let info, child;
+    while ((info = children.next_file(null)) != null) {
+        let type = info.get_file_type();
+        let child = dir.get_child(info.get_name());
+        if (type == Gio.FileType.REGULAR)
+            deleteGFile(child);
+        else if (type == Gio.TypeType.DIRECTORY)
+            recursivelyDeleteDir(child);
+    }
+
+    deleteGFile(dir);
+}
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
index 3dd4e1d..f883070 100644
--- a/js/ui/extensionSystem.js
+++ b/js/ui/extensionSystem.js
@@ -10,6 +10,7 @@ const Shell = imports.gi.Shell;
 const Soup = imports.gi.Soup;
 
 const Config = imports.misc.config;
+const FileUtils = imports.misc.fileUtils;
 
 const API_VERSION = 1;
 
@@ -120,6 +121,37 @@ function installExtensionFromUUID(uuid, version_tag) {
                                });
 }
 
+function uninstallExtensionFromUUID(uuid) {
+    let meta = extensionMeta[uuid];
+    if (!meta)
+        return false;
+
+    // Try to disable it -- if it's ERROR'd, we can't guarantee that,
+    // but it will be removed on next reboot, and hopefully nothing
+    // broke too much.
+    disableExtension(uuid);
+
+    // Don't try to uninstall system extensions
+    if (meta.type != ExtensionType.PER_USER)
+        return false;
+
+    meta.state = ExtensionState.UNINSTALLED;
+    _signals.emit('extension-state-changed', meta);
+
+    delete extensionMeta[uuid];
+
+    // Importers are marked as PERMANENT, so we can't do this.
+    // delete extensions[uuid];
+    extensions[uuid] = undefined;
+
+    delete extensionStateObjs[uuid];
+    delete errors[uuid];
+
+    FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(meta.path));
+
+    return true;
+}
+
 function gotExtensionZipFile(session, message, uuid) {
     if (message.status_code != Soup.KnownStatusCode.OK) {
         logExtensionError(uuid, 'downloading extension: ' + message.status_code);
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index abc7466..ebf0c76 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -48,6 +48,10 @@ const GnomeShellIface = {
               { name: 'InstallRemoteExtension',
                 inSignature: 'ss',
                 outSignature: ''
+              },
+              { name: 'UninstallExtension',
+                inSignature: 's',
+                outSignature: 'b'
               }
              ],
     signals: [{ name: 'ExtensionStatusChanged',
@@ -178,6 +182,10 @@ GnomeShell.prototype = {
         ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
     },
 
+    UninstallExtension: function(uuid) {
+        return ExtensionSystem.uninstallExtensionFromUUID(uuid);
+    },
+
     get OverviewActive() {
         return Main.overview.visible;
     },



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]