~zeller-benjamin/dialer-app/applauncherd

1 by Tiago Salem Herrmann
initial commit
1
/*
2
 * Copyright (C) 2012 Canonical, Ltd.
3
 *
4
 * This file is part of dialer-app.
5
 *
6
 * dialer-app is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; version 3.
9
 *
10
 * dialer-app is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include "dialerapplication.h"
20
21
#include <QDir>
22
#include <QUrl>
154.2.2 by Gustavo Pichorim Boiko
Handle the dialer:// URI.
23
#include <QUrlQuery>
1 by Tiago Salem Herrmann
initial commit
24
#include <QDebug>
25
#include <QStringList>
26
#include <QQuickItem>
27
#include <QQmlComponent>
28
#include <QQmlContext>
29
#include <QQuickView>
30
#include <QDBusInterface>
31
#include <QDBusReply>
32
#include <QDBusConnectionInterface>
33
#include <QLibrary>
34
#include "config.h"
35
#include <QQmlEngine>
233.1.1 by Tiago Salem Herrmann
Add modular MMI support
36
#include <QDir>
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
37
#include <QGuiApplication>
38
515 by Benjamin Zeller
Make the mapplauncherd optional for development
39
#ifdef MAPPLAUNCHERD_ENABLED
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
40
#include <mdeclarativecache5/MDeclarativeCache>
41
#endif
1 by Tiago Salem Herrmann
initial commit
42
43
static void printUsage(const QStringList& arguments)
44
{
45
    qDebug() << "usage:"
46
             << arguments.at(0).toUtf8().constData()
300.2.1 by Olivier Tilloy
Also handle URLs of the form "tel:+1234567890", i.e. without slashes (those are common on web pages).
47
             << "[tel:[///]PHONE_NUMBER]"
48
             << "[tel:[///]voicemail]"
49
             << "[dialer:[///]?view=<view name>]"
1 by Tiago Salem Herrmann
initial commit
50
             << "[--fullscreen]"
51
             << "[--help]"
52
             << "[-testability]";
53
}
54
48.1.1 by Gustavo Pichorim Boiko
Update some icons to use the theme instead of the local assets. Also set the
55
//this is necessary to work on desktop
56
//On desktop use: export DIALER_APP_ICON_THEME=ubuntu-mobile
57
static void installIconPath()
58
{
59
    qDebug() << __PRETTY_FUNCTION__;
60
    QByteArray iconTheme = qgetenv("DIALER_APP_ICON_THEME");
61
    if (!iconTheme.isEmpty()) {
62
        QIcon::setThemeName(iconTheme);
63
    }
64
}
65
66
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
67
DialerApplication::DialerApplication()
68
    : QObject(0), m_view(0), m_applicationIsReady(false), m_fullScreen(false)
1 by Tiago Salem Herrmann
initial commit
69
{
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
70
    qApp->setApplicationName("DialerApp");
71
    qApp->setOrganizationName("com.ubuntu.dialer-app");
1 by Tiago Salem Herrmann
initial commit
72
}
73
74
bool DialerApplication::setup()
75
{
48.1.1 by Gustavo Pichorim Boiko
Update some icons to use the theme instead of the local assets. Also set the
76
    installIconPath();
1 by Tiago Salem Herrmann
initial commit
77
468.2.3 by Tiago Salem Herrmann
Avoid removing # and other characters from tel: uri's
78
    if (mValidSchemes.isEmpty()) {
79
        mValidSchemes << "tel" << "dialer";
1 by Tiago Salem Herrmann
initial commit
80
    }
81
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
82
    QStringList arguments = qApp->arguments();
1 by Tiago Salem Herrmann
initial commit
83
84
    if (arguments.contains("--help")) {
85
        printUsage(arguments);
86
        return false;
87
    }
88
89
    if (arguments.contains("--fullscreen")) {
90
        arguments.removeAll("--fullscreen");
305.2.1 by Gustavo Pichorim Boiko
Switch the dialer-app into full screen mode when greeter is active.
91
        m_fullScreen = true;
1 by Tiago Salem Herrmann
initial commit
92
    }
93
94
    // The testability driver is only loaded by QApplication but not by QGuiApplication.
95
    // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
84.2.1 by Omer Akram
also look for QT_LOAD_TESTABILITY flag in the environment
96
    if (arguments.contains("-testability") || qgetenv("QT_LOAD_TESTABILITY") == "1") {
1 by Tiago Salem Herrmann
initial commit
97
        arguments.removeAll("-testability");
98
        QLibrary testLib(QLatin1String("qttestability"));
99
        if (testLib.load()) {
100
            typedef void (*TasInitialize)(void);
101
            TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
102
            if (initFunction) {
103
                initFunction();
104
            } else {
105
                qCritical("Library qttestability resolve failed!");
106
            }
107
        } else {
108
            qCritical("Library qttestability load failed!");
109
        }
110
    }
111
112
    /* Ubuntu APP Manager gathers info on the list of running applications from the .desktop
113
       file specified on the command line with the desktop_file_hint switch, and will also pass a stage hint
114
       So app will be launched like this:
115
116
       /usr/bin/dialer-app --desktop_file_hint=/usr/share/applications/dialer-app.desktop
117
                          --stage_hint=main_stage
118
119
       So remove whatever --arg still there before continue parsing
120
    */
121
    for (int i = arguments.count() - 1; i >=0; --i) {
122
        if (arguments[i].startsWith("--")) {
123
            arguments.removeAt(i);
124
        }
125
    }
126
127
    if (arguments.size() == 2) {
128
        QUrl uri(arguments.at(1));
468.2.3 by Tiago Salem Herrmann
Avoid removing # and other characters from tel: uri's
129
        if (mValidSchemes.contains(uri.scheme())) {
1 by Tiago Salem Herrmann
initial commit
130
            m_arg = arguments.at(1);
131
        }
132
    }
515 by Benjamin Zeller
Make the mapplauncherd optional for development
133
#ifdef MAPPLAUNCHERD_ENABLED
134
    m_view = MDeclarativeCache::qQuickView();
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
135
#else
1 by Tiago Salem Herrmann
initial commit
136
    m_view = new QQuickView();
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
137
#endif
1 by Tiago Salem Herrmann
initial commit
138
    QObject::connect(m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(onViewStatusChanged(QQuickView::Status)));
514 by Benjamin Zeller
Prepare dialer-app for mapplauncherd
139
    QObject::connect(m_view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
1 by Tiago Salem Herrmann
initial commit
140
    m_view->setResizeMode(QQuickView::SizeRootObjectToView);
141
    m_view->setTitle("Dialer");
142
    m_view->rootContext()->setContextProperty("application", this);
139.1.1 by Gustavo Pichorim Boiko
Fix the loading of dialer-app's i18n.
143
    m_view->rootContext()->setContextProperty("i18nDirectory", I18N_DIRECTORY);
475.1.1 by Gustavo Pichorim Boiko
Restrict the window resizing in desktop mode.
144
    m_view->rootContext()->setContextProperty("view", m_view);
1 by Tiago Salem Herrmann
initial commit
145
    m_view->engine()->setBaseUrl(QUrl::fromLocalFile(dialerAppDirectory()));
146
89.3.1 by Gustavo Pichorim Boiko
Make it possible to override the default contact manager.
147
    // check if there is a contacts backend override
89.3.3 by Gustavo Pichorim Boiko
Update the code to use the same env var as qtpim uses for that.
148
    QString contactsBackend = qgetenv("QTCONTACTS_MANAGER_OVERRIDE");
89.3.1 by Gustavo Pichorim Boiko
Make it possible to override the default contact manager.
149
    if (!contactsBackend.isEmpty()) {
150
        qDebug() << "Overriding the contacts backend, using:" << contactsBackend;
89.3.3 by Gustavo Pichorim Boiko
Update the code to use the same env var as qtpim uses for that.
151
        m_view->rootContext()->setContextProperty("QTCONTACTS_MANAGER_OVERRIDE", contactsBackend);
89.3.1 by Gustavo Pichorim Boiko
Make it possible to override the default contact manager.
152
    }
153
398.1.10 by Renato Araujo Oliveira Filho
Create autopilot test for contacts page.
154
    // used by autopilot tests to load vcards during tests
155
    QByteArray testData = qgetenv("QTCONTACTS_PRELOAD_VCARD");
156
    m_view->rootContext()->setContextProperty("QTCONTACTS_PRELOAD_VCARD", testData);
157
1 by Tiago Salem Herrmann
initial commit
158
    QString pluginPath = ubuntuPhonePluginPath();
159
    if (!pluginPath.isNull()) {
160
        m_view->engine()->addImportPath(pluginPath);
161
    }
162
163
    m_view->setSource(QUrl::fromLocalFile("dialer-app.qml"));
305.2.1 by Gustavo Pichorim Boiko
Switch the dialer-app into full screen mode when greeter is active.
164
    if (m_fullScreen) {
1 by Tiago Salem Herrmann
initial commit
165
        m_view->showFullScreen();
166
    } else {
167
        m_view->show();
168
    }
169
170
    return true;
171
}
172
305.2.1 by Gustavo Pichorim Boiko
Switch the dialer-app into full screen mode when greeter is active.
173
bool DialerApplication::fullScreen() const
174
{
175
    return m_fullScreen;
176
}
177
178
void DialerApplication::setFullScreen(bool value)
179
{
180
    m_fullScreen = value;
181
    m_view->setWindowState(m_fullScreen ? Qt::WindowFullScreen : Qt::WindowNoState);
182
    Q_EMIT fullScreenChanged();
183
}
184
1 by Tiago Salem Herrmann
initial commit
185
DialerApplication::~DialerApplication()
186
{
187
    if (m_view) {
188
        delete m_view;
189
    }
190
}
191
192
void DialerApplication::onViewStatusChanged(QQuickView::Status status)
193
{
194
    if (status != QQuickView::Ready) {
195
        return;
196
    }
197
109.3.1 by Gustavo Pichorim Boiko
Do not wait for the telepathy stuff to get ready to process the command line
198
    onApplicationReady();
1 by Tiago Salem Herrmann
initial commit
199
}
200
201
void DialerApplication::onApplicationReady()
202
{
203
    m_applicationIsReady = true;
204
    parseArgument(m_arg);
205
    m_arg.clear();
206
}
207
208
void DialerApplication::parseArgument(const QString &arg)
209
{
210
    if (arg.isEmpty()) {
211
        return;
212
    }
213
60.3.1 by Gustavo Pichorim Boiko
Change the dialer-app to use the new URL dispatcher mechanism.
214
    QUrl url(arg);
215
    QString scheme = url.scheme();
468.2.3 by Tiago Salem Herrmann
Avoid removing # and other characters from tel: uri's
216
    // we can't fill value with url.path() as it might contain the # character and QUrl will drop it.
217
    QString value;
218
    if (!mValidSchemes.contains(url.scheme())) {
219
        qWarning() << "Url scheme not valid for dialer-app";
220
        return;
221
    } else if (url.scheme() == "tel") {
222
        // remove the initial tel:, it doesn't matter if it contains /// or //, as we
223
        // now use libphonenumber and it will remove these invalid characters when in the beginning
224
        // of the number
468.2.4 by Tiago Salem Herrmann
use remove() instead of mid()
225
        value = arg;
226
        value = QUrl::fromPercentEncoding(value.remove("tel:").toLatin1());
300.2.1 by Olivier Tilloy
Also handle URLs of the form "tel:+1234567890", i.e. without slashes (those are common on web pages).
227
    }
1 by Tiago Salem Herrmann
initial commit
228
229
    QQuickItem *mainView = m_view->rootObject();
230
    if (!mainView) {
231
        return;
232
    }
233
60.3.1 by Gustavo Pichorim Boiko
Change the dialer-app to use the new URL dispatcher mechanism.
234
    if (scheme == "tel") {
235
        if (value == "voicemail") {
125.3.41 by Gustavo Pichorim Boiko
Fix the page navigation and make sure numbers are not called directly, and just
236
            // FIXME: check if we should call the voicemail directly or just populate it
60.3.1 by Gustavo Pichorim Boiko
Change the dialer-app to use the new URL dispatcher mechanism.
237
            QMetaObject::invokeMethod(mainView, "callVoicemail");
238
        } else {
125.3.41 by Gustavo Pichorim Boiko
Fix the page navigation and make sure numbers are not called directly, and just
239
            // do not call the number directly, instead only populate the dialpad view
240
            QMetaObject::invokeMethod(mainView, "populateDialpad", Q_ARG(QVariant, value), Q_ARG(QVariant, QString()));
60.3.1 by Gustavo Pichorim Boiko
Change the dialer-app to use the new URL dispatcher mechanism.
241
        }
154.2.2 by Gustavo Pichorim Boiko
Handle the dialer:// URI.
242
    } else if (scheme == "dialer") {
243
        QUrlQuery query(url);
244
        QString viewName = query.queryItemValue("view");
245
        if (viewName == "liveCall") {
433.1.9 by Tiago Salem Herrmann
update method signature
246
            QMetaObject::invokeMethod(mainView, "switchToLiveCall", Q_ARG(QVariant, QVariant()), Q_ARG(QVariant, QVariant()));
154.2.2 by Gustavo Pichorim Boiko
Handle the dialer:// URI.
247
        }
248
1 by Tiago Salem Herrmann
initial commit
249
    }
250
}
251
252
void DialerApplication::activateWindow()
253
{
254
    if (m_view) {
255
        m_view->raise();
256
        m_view->requestActivate();
257
    }
258
}
233.1.1 by Tiago Salem Herrmann
Add modular MMI support
259
260
QStringList DialerApplication::mmiPluginList()
261
{
262
    QStringList plugins;
263
    QString mmiDirectory = dialerAppDirectory() + "/MMI";
264
    QString mmiCustomDirectory = "/custom" + mmiDirectory;
265
    QDir directory(mmiDirectory);
266
    QDir customDirectory(mmiCustomDirectory);
267
    Q_FOREACH(const QString &file, directory.entryList(QStringList() << "*.qml")) {
268
        plugins << directory.filePath(file);
269
    }
270
    Q_FOREACH(const QString &file, customDirectory.entryList(QStringList() << "*.qml")) {
271
        plugins << customDirectory.filePath(file);
272
    }
273
    return plugins;
274
}