osx: Implement auto-upgrade function using Sparkle
During the upgrade, NFD and ndn-autoupdate will be stopped (and, if
enabled, automatically started with new versions).
Change-Id: I010ae4a8aa6f99a0039d58065ab7eb0c9189a979
diff --git a/src/Info.plist b/src/Info.plist
index 40eda16..6bb818d 100644
--- a/src/Info.plist
+++ b/src/Info.plist
@@ -33,7 +33,7 @@
<key>LSUIElement</key>
<string>1</string>
<key>SUFeedURL</key>
- <string>http://named-data.net/binaries/ndn-appcast.xml</string>
+ <string>https://irl.cs.ucla.edu/~cawka/ndn-control-center.xml</string>
<key>SUPublicDSAKeyFile</key>
<string>ndn_sparkle_pub.pem</string>
</dict>
diff --git a/src/main.cpp b/src/main.cpp
index d03f0cd..e39e70c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -140,7 +140,7 @@
ForwarderStatusModel m_forwarderStatusModel;
FibStatusModel m_fibModel;
- TrayMenu m_tray;
+ ncc::TrayMenu m_tray;
};
} // namespace ndn
diff --git a/src/osx-auto-update-sparkle.hpp b/src/osx-auto-update-sparkle.hpp
new file mode 100644
index 0000000..716f1dc
--- /dev/null
+++ b/src/osx-auto-update-sparkle.hpp
@@ -0,0 +1,53 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017, Regents of the University of California.
+ *
+ * This file is part of NFD Control Center. See AUTHORS.md for complete list of NFD
+ * authors and contributors.
+ *
+ * NFD Control Center is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD Control Center is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with NFD
+ * Control Center, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NCC_OSX_AUTO_UPDATE_SPARKLE_HPP
+#define NCC_OSX_AUTO_UPDATE_SPARKLE_HPP
+
+#include "config.hpp"
+
+#ifndef OSX_BUILD
+#error "Cannot be included for non-OSX build"
+#endif // OSX_BUILD
+
+#include <string>
+#include <ndn-cxx/util/backports.hpp>
+
+namespace ndn {
+namespace ncc {
+
+class OsxAutoUpdateSparkle
+{
+public:
+ OsxAutoUpdateSparkle(const std::string& updateUrl);
+
+ ~OsxAutoUpdateSparkle();
+
+ void
+ checkForUpdates();
+
+private:
+ class Impl;
+ unique_ptr<Impl> m_impl;
+};
+
+} // namespace ncc
+} // namespace ndn
+
+#endif // NCC_OSX_AUTO_UPDATE_SPARKLE_HPP
diff --git a/src/osx-auto-update-sparkle.mm b/src/osx-auto-update-sparkle.mm
new file mode 100644
index 0000000..a4e5a0f
--- /dev/null
+++ b/src/osx-auto-update-sparkle.mm
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017, Regents of the University of California.
+ *
+ * This file is part of NFD Control Center. See AUTHORS.md for complete list of NFD
+ * authors and contributors.
+ *
+ * NFD Control Center is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD Control Center is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with NFD
+ * Control Center, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "osx-auto-update-sparkle.hpp"
+
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+#import <Sparkle/Sparkle.h>
+
+@interface UpdaterDelegate : NSObject<SUUpdaterDelegate> {
+ ndn::ncc::OsxAutoUpdateSparkle* this_;
+}
+
+- (void)setSelf:(ndn::ncc::OsxAutoUpdateSparkle*)ptr;
+
+- (BOOL)updater:(SUUpdater *)updater
+ shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update
+ untilInvoking:(NSInvocation *)invocation;
+
+@end
+
+@implementation UpdaterDelegate
+
+- (void)setSelf:(ndn::ncc::OsxAutoUpdateSparkle*)ptr
+{
+ this_ = ptr;
+}
+
+- (BOOL)updater:(SUUpdater *)updater
+ shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update
+ untilInvoking:(NSInvocation *)invocation
+{
+ NSTask *task = [[NSTask alloc] init];
+ task.launchPath = @"/usr/bin/killall";
+ task.arguments = @[@"ndn-autoconfig", @"nfd"];
+ [task launch];
+ return NO;
+}
+
+@end
+
+namespace ndn {
+namespace ncc {
+
+class OsxAutoUpdateSparkle::Impl
+{
+public:
+ SUUpdater* m_updater;
+ UpdaterDelegate* delegate;
+};
+
+OsxAutoUpdateSparkle::OsxAutoUpdateSparkle(const std::string& updateUrl)
+ : m_impl(make_unique<Impl>())
+{
+ m_impl->m_updater = [[SUUpdater sharedUpdater] retain];
+ NSURL* url = [NSURL URLWithString:[NSString stringWithUTF8String:updateUrl.data()]];
+ [m_impl->m_updater setFeedURL:url];
+ [m_impl->m_updater setAutomaticallyChecksForUpdates:YES];
+ [m_impl->m_updater setUpdateCheckInterval:86400];
+
+ m_impl->delegate = [[UpdaterDelegate alloc] init];
+ [m_impl->delegate setSelf:this];
+ [m_impl->m_updater setDelegate:m_impl->delegate];
+}
+
+OsxAutoUpdateSparkle::~OsxAutoUpdateSparkle()
+{
+ [m_impl->m_updater release];
+ // presummably SUUpdater handles garbage collection
+}
+
+void
+OsxAutoUpdateSparkle::checkForUpdates()
+{
+ //[m_impl->m_updater checkForUpdatesInBackground];
+ [m_impl->m_updater checkForUpdates:nil];
+}
+
+} // namespace ncc
+} // namespace ndn
diff --git a/src/tray-menu.cpp b/src/tray-menu.cpp
index d4d2637..2ec3cb4 100644
--- a/src/tray-menu.cpp
+++ b/src/tray-menu.cpp
@@ -35,6 +35,7 @@
#endif // OSX_BUILD
namespace ndn {
+namespace ncc {
TrayMenu::TrayMenu(QQmlContext* context, Face& face)
: m_context(context)
@@ -42,24 +43,22 @@
, m_menu(new QMenu(this))
, m_entryPref(new QAction("Preferences...", m_menu))
, m_entrySec(new QAction("Security...", m_menu))
+ , m_acProc(new QProcess())
+ , m_settings(new QSettings())
#ifdef OSX_BUILD
, m_entryEnableCli(new QAction("Enable Command Terminal Usage...", m_menu))
+ , m_checkForUpdates(new QAction("Check for updates", m_menu))
+ , m_sparkle("https://irl.cs.ucla.edu/~cawka/ndn-control-center.xml")
#endif
, m_entryQuit(new QAction("Quit", m_menu))
, m_keyViewerDialog(new ncc::KeyViewerDialog)
, m_face(face)
- , m_acProc(new QProcess())
- , m_settings(new QSettings())
{
connect(m_entryPref, SIGNAL(triggered()), this, SIGNAL(showApp()));
connect(this, SIGNAL(showApp()), this, SLOT(showPref()));
connect(m_entrySec, SIGNAL(triggered()), m_keyViewerDialog, SLOT(present()));
connect(m_entryQuit, SIGNAL(triggered()), this, SLOT(quitApp()));
-#ifdef OSX_BUILD
- connect(m_entryEnableCli, SIGNAL(triggered()), this, SLOT(enableCli()));
-#endif
-
connect(this, SIGNAL(nfdActivityUpdate(bool)), this, SLOT(updateNfdActivityIcon(bool)),
Qt::QueuedConnection);
@@ -69,7 +68,11 @@
m_menu->addAction(m_entryPref);
m_menu->addAction(m_entrySec);
#ifdef OSX_BUILD
+ connect(m_entryEnableCli, SIGNAL(triggered()), this, SLOT(enableCli()));
m_menu->addAction(m_entryEnableCli);
+
+ connect(m_checkForUpdates, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
+ m_menu->addAction(m_checkForUpdates);
#endif
m_menu->addAction(m_entryQuit);
m_tray = new QSystemTrayIcon(this);
@@ -284,7 +287,6 @@
connect(addNewRoute,SIGNAL(finished(int)), addNewRoute, SLOT(deleteLater()));
addNewRoute->start("bash", QStringList() << "-c" << cmd);
std::cout << "Done" << std::endl;
-
}
void
@@ -347,4 +349,13 @@
#endif
}
+#ifdef OSX_BUILD
+void
+TrayMenu::checkForUpdates()
+{
+ m_sparkle.checkForUpdates();
+}
+#endif // OSX_BUILD
+
+} // namespace ncc
} // namespace ndn
diff --git a/src/tray-menu.hpp b/src/tray-menu.hpp
index 3c7b0f0..841f068 100644
--- a/src/tray-menu.hpp
+++ b/src/tray-menu.hpp
@@ -39,10 +39,16 @@
#include "key-viewer-dialog.hpp"
+#ifdef OSX_BUILD
+#include "osx-auto-update-sparkle.hpp"
+#endif // OSX_BUILD
+
namespace ndn {
class Face;
+namespace ncc {
+
class TrayMenu : public QWidget
{
Q_OBJECT
@@ -113,6 +119,11 @@
static void
appendMsg(QString &target, QString source);
+#ifdef OSX_BUILD
+ void
+ checkForUpdates();
+#endif // OSX_BUILD
+
private:
QQmlContext* m_context;
bool m_isNfdRunning;
@@ -125,7 +136,9 @@
QSettings m_settings;
#ifdef OSX_BUILD
QAction* m_entryEnableCli;
-#endif
+ QAction* m_checkForUpdates;
+ OsxAutoUpdateSparkle m_sparkle;
+#endif // OSX_BUILD
QAction* m_entryQuit;
@@ -133,6 +146,7 @@
Face& m_face;
};
+} // namespace ncc
} // namespace ndn
#endif // NCC_TRAY_MENU_HPP