Commit 8d25becf authored by Rafael Roquetto's avatar Rafael Roquetto

BlackBerry Development Environment Setup Wizard

This wizard tries to make the process of setting up a new development
environment for BlackBerry devices easy. It does not implement anything that
isn't already available through the BlackBerry category under the "options"
menu, and also imposes some restrictions for the sake of simplicity.

It will:

* register CSJ keys
* create developer certificate
* create SSH keys to a default location
* request a debug token
* upload a debug token to the device

Change-Id: I063ee107fb474135523cf685b7ac5d05096ef741
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent c426b713
......@@ -256,18 +256,34 @@ void BlackBerryConfiguration::syncCertificates(QList<BlackBerryCertificate*> cer
m_config.activeCertificate = activeCertificate;
foreach (BlackBerryCertificate *cert, m_config.certificates) {
if (!certificates.contains(cert)) {
m_config.certificates.removeAll(cert);
delete cert;
}
if (!certificates.contains(cert))
removeCertificate(cert);
}
foreach (BlackBerryCertificate *cert, certificates) {
if (!m_config.certificates.contains(cert)) {
cert->setParent(this);
m_config.certificates << cert;
}
}
foreach (BlackBerryCertificate *cert, certificates)
addCertificate(cert);
}
void BlackBerryConfiguration::addCertificate(BlackBerryCertificate *certificate)
{
if (m_config.certificates.contains(certificate))
return;
if (m_config.certificates.isEmpty())
m_config.activeCertificate = certificate;
certificate->setParent(this);
m_config.certificates << certificate;
}
void BlackBerryConfiguration::removeCertificate(BlackBerryCertificate *certificate)
{
if (m_config.activeCertificate == certificate)
m_config.activeCertificate = 0;
m_config.certificates.removeAll(certificate);
delete certificate;
}
QList<BlackBerryCertificate*> BlackBerryConfiguration::certificates() const
......@@ -470,6 +486,11 @@ QString BlackBerryConfiguration::defaultKeystorePath() const
return dataDirPath() + QLatin1String("/author.p12");
}
QString BlackBerryConfiguration::defaultDebugTokenPath() const
{
return dataDirPath() + QLatin1String("/debugtoken.bar");
}
// TODO: QnxUtils::parseEnvFile() and qnxEnv() to return Util::Enviroment instead(?)
QMultiMap<QString, QString> BlackBerryConfiguration::qnxEnv() const
{
......
......@@ -85,11 +85,14 @@ public:
QString barsignerDbPath() const;
QString dataDirPath() const;
QString defaultKeystorePath() const;
QString defaultDebugTokenPath() const;
void loadSettings();
void clearNdkSettings();
void cleanNdkConfiguration();
void syncCertificates(QList<BlackBerryCertificate*> certificates,
BlackBerryCertificate *activeCertificate);
void addCertificate(BlackBerryCertificate *certificate);
void removeCertificate(BlackBerryCertificate *certificate);
QList<BlackBerryCertificate*> certificates() const;
BlackBerryCertificate *activeCertificate();
......
......@@ -80,7 +80,7 @@ QString BlackBerryDeviceInformation::hardwareId() const
void BlackBerryDeviceInformation::processData(const QString &line)
{
if (line.startsWith(QLatin1String("devicepin::")))
m_devicePin = line.split(QLatin1String("::")).at(1).trimmed();
m_devicePin = line.split(QLatin1String("::0x")).at(1).trimmed();
else if (line.startsWith(QLatin1String("device_os::")))
m_deviceOS = line.split(QLatin1String("::")).at(1).trimmed();
else if (line.startsWith(QLatin1String("hardwareid::")))
......
......@@ -36,6 +36,7 @@
#include "blackberryimportcertificatedialog.h"
#include "blackberrycreatecertificatedialog.h"
#include "blackberrycertificate.h"
#include "blackberryutils.h"
#include "ui_blackberrykeyswidget.h"
#include <QFileInfo>
......@@ -175,7 +176,7 @@ void BlackBerryKeysWidget::handleSelectionChanged(const QItemSelection &selected
void BlackBerryKeysWidget::updateRegisterSection()
{
if (hasRegisteredKey()) {
if (BlackBerryUtils::hasRegisteredKeys()) {
m_ui->registerButton->hide();
m_ui->unregisterButton->show();
m_ui->registeredLabel->setText(tr("Registered: Yes"));
......@@ -186,24 +187,6 @@ void BlackBerryKeysWidget::updateRegisterSection()
}
}
bool BlackBerryKeysWidget::hasRegisteredKey() const
{
BlackBerryConfiguration &configuration = BlackBerryConfiguration::instance();
QFileInfo cskFile(configuration.barsignerCskPath());
if (!cskFile.exists())
return false;
QFileInfo dbFile(configuration.barsignerDbPath());
if (!dbFile.exists())
return false;
return true;
}
} // namespace Internal
} // namespace Qnx
......@@ -68,8 +68,6 @@ private slots:
private:
void updateRegisterSection();
bool hasRegisteredKey() const;
QString dataDir() const;
QString cskFilePath() const;
QString dbFilePath() const;
......
......@@ -32,6 +32,8 @@
#include "blackberryndksettingswidget.h"
#include "ui_blackberryndksettingswidget.h"
#include "qnxutils.h"
#include "blackberryutils.h"
#include "blackberrysetupwizard.h"
#include <utils/pathchooser.h>
......@@ -50,19 +52,62 @@ BlackBerryNDKSettingsWidget::BlackBerryNDKSettingsWidget(QWidget *parent) :
m_ui->setupUi(this);
m_ui->sdkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
m_ui->sdkPath->setPath(m_bbConfig->ndkPath());
m_hasValidSdkPath = QnxUtils::isValidNdkPath(m_ui->sdkPath->path());
initInfoTable();
connect(m_ui->wizardButton, SIGNAL(clicked()), this, SLOT(launchBlackBerrySetupWizard()));
connect(m_ui->sdkPath, SIGNAL(changed(QString)), this, SLOT(checkSdkPath()));
connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(cleanConfiguration()));
connect(m_bbConfig, SIGNAL(updated()), this, SLOT(updateInfoTable()));
}
void BlackBerryNDKSettingsWidget::setRemoveButtonVisible(bool visible)
{
m_ui->removeButton->setVisible(visible);
}
void BlackBerryNDKSettingsWidget::setWizardMessageVisible(bool visible)
{
m_ui->wizardLabel->setVisible(visible);
m_ui->wizardButton->setVisible(visible);
}
QString BlackBerryNDKSettingsWidget::sdkPath() const
{
return m_ui->sdkPath->path();
}
void BlackBerryNDKSettingsWidget::launchBlackBerrySetupWizard() const
{
const bool alreadyConfigured = BlackBerryUtils::hasRegisteredKeys();
if (alreadyConfigured) {
QMessageBox::information(0, tr("Qt Creator"),
tr("It appears that your BlackBerry environment has already been configured."));
return;
}
BlackBerrySetupWizard wizard;
wizard.exec();
}
void BlackBerryNDKSettingsWidget::checkSdkPath()
{
if (!m_ui->sdkPath->path().isEmpty() &&
QnxUtils::isValidNdkPath(m_ui->sdkPath->path()))
QnxUtils::isValidNdkPath(m_ui->sdkPath->path())) {
m_bbConfig->setupNdkConfiguration(m_ui->sdkPath->path());
m_hasValidSdkPath = true;
} else {
m_hasValidSdkPath = false;
}
emit sdkPathChanged(m_ui->sdkPath->path());
}
bool BlackBerryNDKSettingsWidget::hasValidSdkPath() const
{
return m_hasValidSdkPath;
}
void BlackBerryNDKSettingsWidget::updateInfoTable()
......
......@@ -50,10 +50,18 @@ class BlackBerryNDKSettingsWidget : public QWidget
public:
explicit BlackBerryNDKSettingsWidget(QWidget *parent = 0);
void setRemoveButtonVisible(bool visible);
void setWizardMessageVisible(bool visible);
QString sdkPath() const;
bool hasValidSdkPath() const;
signals:
void sdkPathChanged();
void sdkPathChanged(const QString &newPath);
public slots:
void launchBlackBerrySetupWizard() const;
void checkSdkPath();
void updateInfoTable();
void clearInfoTable();
......@@ -61,10 +69,10 @@ public slots:
private:
void initInfoTable();
QString m_sdkPath;
Ui_BlackBerryNDKSettingsWidget *m_ui;
BlackBerryConfiguration *m_bbConfig;
QStandardItemModel *m_infoModel;
bool m_hasValidSdkPath;
};
......
......@@ -6,42 +6,173 @@
<rect>
<x>0</x>
<y>0</y>
<width>794</width>
<height>473</height>
<width>773</width>
<height>443</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="wizardLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>Get started and configure your environment:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="wizardButton">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>13</red>
<green>131</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>13</red>
<green>131</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>13</red>
<green>131</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>13</red>
<green>131</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>144</red>
<green>141</green>
<blue>139</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>150</red>
<green>147</green>
<blue>145</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<italic>false</italic>
<underline>true</underline>
</font>
</property>
<property name="text">
<string>BlackBerry NDK Path </string>
<string>environment setup wizard</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="sdkPath" native="true"/>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>276</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>BlackBerry NDK Path </string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="sdkPath" native="true"/>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTableView" name="ndkInfosTableView"/>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTableView" name="ndkInfosTableView"/>
</item>
</layout>
</widget>
<customwidgets>
......
......@@ -33,6 +33,7 @@
#include "blackberrycsjregistrar.h"
#include "blackberryconfiguration.h"
#include "blackberrycertificate.h"
#include "blackberryutils.h"
#include "ui_blackberryregisterkeydialog.h"
#include <QFileDialog>
......@@ -273,7 +274,7 @@ BlackBerryCertificate * BlackBerryRegisterKeyDialog::certificate() const
void BlackBerryRegisterKeyDialog::generateDeveloperCertificate()
{
m_certificate = new BlackBerryCertificate(keystorePath(),
getCsjAuthor(rdkPath()), keystorePassword());
BlackBerryUtils::getCsjAuthor(rdkPath()), keystorePassword());
connect(m_certificate, SIGNAL(finished(int)), this, SLOT(certificateCreated(int)));
......@@ -312,30 +313,6 @@ void BlackBerryRegisterKeyDialog::setBusy(bool busy)
}
QString BlackBerryRegisterKeyDialog::getCsjAuthor(const QString &fileName) const
{
QFile file(fileName);
QString author = QLatin1String("Unknown Author");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return author;
QTextStream stream(&file);
while (!stream.atEnd()) {
QString line = stream.readLine();
if (line.startsWith(QLatin1String("Company="))) {
author = line.remove(QLatin1String("Company=")).trimmed();
break;
}
}
file.close();
return author;
}
void BlackBerryRegisterKeyDialog::setupCsjPathChooser(Utils::PathChooser *chooser)
{
chooser->setExpectedKind(Utils::PathChooser::File);
......
......@@ -81,8 +81,6 @@ private:
void cleanup() const;
void setBusy(bool busy);
QString getCsjAuthor(const QString &fileName) const;
Ui_BlackBerryRegisterKeyDialog *m_ui;
BlackBerryCsjRegistrar *m_registrar;
......
This diff is collapsed.
/**************************************************************************
**
** Copyright (C) 2011 - 2013 Research In Motion
**
** Contact: Research In Motion (blackberry-qt@qnx.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef BLACKBERRYSETUPWIZARD_H
#define BLACKBERRYSETUPWIZARD_H
#include <QWizard>
#include <QList>
#include <QByteArray>
#include <projectexplorer/devicesupport/idevice.h>
namespace QSsh {
class SshKeyGenerator;
}
namespace Qnx {
namespace Internal {
class BlackBerrySetupWizardWelcomePage;
class BlackBerrySetupWizardNdkPage;
class BlackBerrySetupWizardKeysPage;
class BlackBerrySetupWizardDevicePage;
class BlackBerrySetupWizardFinishPage;
class BlackBerryCsjRegistrar;
class BlackBerryCertificate;
class BlackBerryDeviceInformation;
class BlackBerryDebugTokenRequester;
class BlackBerryDebugTokenUploader;
class BlackBerrySetupWizard : public QWizard
{
Q_OBJECT
public:
explicit BlackBerrySetupWizard(QWidget *parent = 0);
virtual ~BlackBerrySetupWizard();
public slots:
void accept();
signals:
void stepFinished();
private slots:
void processNextStep();
void deviceInfoFinished(int status);
void registrarFinished(int status, const QString &errorString);
void certificateCreated(int status);
void debugTokenArrived(int status);
void uploaderFinished(int status);
void requestDevicePin();
void createKeys();
void generateDeveloperCertificate();
void generateSshKeys();
void requestDebugToken();
void uploadDebugToken();
void writeDeviceInformation();
private:
enum PageId {
WelcomePageId,
NdkPageId,
KeysPageId,
DevicePageId,
FinishPageId
};
struct Step {
QByteArray slot;
QString message;
};
void registerStep(const QByteArray &slot, const QString &message);
void setBusy(bool busy);
void cleanupFiles() const;
void reset();
QString privateKeyPath() const;
QString publicKeyPath() const;
QString deviceName() const;
QString storeLocation() const;
QString rdkPath() const;
QString pbdtPath() const;
QString csjPin() const;
QString password() const;
QString devicePassword() const;
QString hostName() const;
bool isPhysicalDevice() const;
ProjectExplorer::IDevice::Ptr device();
BlackBerrySetupWizardWelcomePage *m_welcomePage;
BlackBerrySetupWizardNdkPage *m_ndkPage;
BlackBerrySetupWizardKeysPage *m_keysPage;
BlackBerrySetupWizardDevicePage *m_devicePage;
BlackBerrySetupWizardFinishPage *m_finishPage;
BlackBerryCsjRegistrar *m_registrar;
BlackBerryCertificate *m_certificate;
BlackBerryDeviceInformation *m_deviceInfo;
BlackBerryDebugTokenRequester *m_requester;
BlackBerryDebugTokenUploader *m_uploader;
QSsh::SshKeyGenerator *m_keyGenerator;
QString m_devicePin;
QList<Step*> m_stepList;
int m_currentStep;
int m_stepOffset;
};
} // namespace Qnx
} // namespace Internal
#endif // BLACKBERRYSETUPWIZARD_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Qnx::Internal::BlackBerrySetupWizardDevicePage</class>
<widget class="QWizardPage" name="Qnx::Internal::BlackBerrySetupWizardDevicePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>159</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Device name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="deviceName">
<property name="placeholderText">
<string>IP or host name of the device</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Device IP address:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="ipAddress"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Device password:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="password">