Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
22 andreas 1
/*
2
 * Copyright (C) 2021 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <iostream>
20
#include <fstream>
120 andreas 21
#include <functional>
22 andreas 22
 
118 andreas 23
#include <stdio.h>
50 andreas 24
#include <sys/stat.h>
25
#include <fcntl.h>
26
#include <errno.h>
118 andreas 27
#include <unistd.h>
50 andreas 28
 
22 andreas 29
#include <QFile>
43 andreas 30
#ifdef __ANDROID__
31
#include <QtAndroid>
32
#endif
33
#include <QMap>
34
#include <QHash>
22 andreas 35
 
36
#include "ttpinit.h"
37
#include "terror.h"
50 andreas 38
#include "tvalidatefile.h"
115 andreas 39
#include "tconfig.h"
40
#include "tfsfreader.h"
119 andreas 41
#include "tdirectory.h"
22 andreas 42
 
43
using std::string;
85 andreas 44
using std::vector;
22 andreas 45
using std::ostream;
120 andreas 46
using std::bind;
22 andreas 47
 
51 andreas 48
TTPInit::TTPInit()
49
{
50
    DECL_TRACER("TTPInit::TTPInit()");
51
}
52
 
22 andreas 53
TTPInit::TTPInit(const string& path)
54
    : mPath(path)
55
{
56
    DECL_TRACER("TTPInit::TTPInit(const string& path)")
57
 
50 andreas 58
    createDirectoryStructure();
22 andreas 59
    createPanelConfigs();
115 andreas 60
    loadSurfaceFromController();
22 andreas 61
}
62
 
63
bool TTPInit::createPanelConfigs()
64
{
65
    DECL_TRACER("TTPInit::createPanelConfigs()");
66
 
113 andreas 67
    vector<string> resFiles = {
68
        ":ressources/external.xma",
69
        ":ressources/fnt.xma",
70
        ":ressources/icon.xma",
71
        ":ressources/_main.xml",
72
        ":ressources/manifest.xma",
73
        ":ressources/map.xma",
74
        ":ressources/pal_001.xma",
75
        ":ressources/prj.xma",
76
        ":ressources/_setup.xml",
77
        ":ressources/table.xma",
78
        ":ressources/fonts/arial.ttf",
79
        ":ressources/images/theosys_logo.png",
80
        ":ressources/__system/graphics/fonts/amxbold_.ttf",
81
        ":ressources/__system/graphics/fonts/arialbd.ttf",
82
        ":ressources/__system/graphics/fonts/arial.ttf",
83
        ":ressources/__system/graphics/fonts/cour.ttf",
84
        ":ressources/__system/graphics/sounds/audioTest.wav",
85
        ":ressources/__system/graphics/sounds/docked.mp3",
86
        ":ressources/__system/graphics/sounds/doubleBeep01.wav",
87
        ":ressources/__system/graphics/sounds/doubleBeep02.wav",
88
        ":ressources/__system/graphics/sounds/doubleBeep03.wav",
89
        ":ressources/__system/graphics/sounds/doubleBeep04.wav",
90
        ":ressources/__system/graphics/sounds/doubleBeep05.wav",
91
        ":ressources/__system/graphics/sounds/doubleBeep06.wav",
92
        ":ressources/__system/graphics/sounds/doubleBeep07.wav",
93
        ":ressources/__system/graphics/sounds/doubleBeep08.wav",
94
        ":ressources/__system/graphics/sounds/doubleBeep09.wav",
95
        ":ressources/__system/graphics/sounds/doubleBeep10.wav",
96
        ":ressources/__system/graphics/sounds/doubleBeep.wav",
97
        ":ressources/__system/graphics/sounds/ringback.wav",
98
        ":ressources/__system/graphics/sounds/ringtone.wav",
99
        ":ressources/__system/graphics/sounds/singleBeep01.wav",
100
        ":ressources/__system/graphics/sounds/singleBeep02.wav",
101
        ":ressources/__system/graphics/sounds/singleBeep03.wav",
102
        ":ressources/__system/graphics/sounds/singleBeep04.wav",
103
        ":ressources/__system/graphics/sounds/singleBeep05.wav",
104
        ":ressources/__system/graphics/sounds/singleBeep06.wav",
105
        ":ressources/__system/graphics/sounds/singleBeep07.wav",
106
        ":ressources/__system/graphics/sounds/singleBeep08.wav",
107
        ":ressources/__system/graphics/sounds/singleBeep09.wav",
108
        ":ressources/__system/graphics/sounds/singleBeep10.wav",
109
        ":ressources/__system/graphics/sounds/singleBeep.wav",
110
        ":ressources/__system/graphics/draw.xma",
111
        ":ressources/__system/graphics/fnt.xma",
112
        ":ressources/__system/graphics/version.xma"
113
    };
114
 
22 andreas 115
    bool err = false;
113 andreas 116
    vector<string>::iterator iter;
22 andreas 117
 
113 andreas 118
    for (iter = resFiles.begin(); iter != resFiles.end(); ++iter)
22 andreas 119
    {
113 andreas 120
        if (!copyFile(*iter))
50 andreas 121
            err = true;
22 andreas 122
    }
123
 
124
 
125
    return err;
126
}
51 andreas 127
 
117 andreas 128
bool TTPInit::createSystemConfigs()
129
{
130
    DECL_TRACER("TTPInit::createSystemConfigs()");
131
 
132
    vector<string> resFiles = {
133
        ":ressources/__system/graphics/fonts/amxbold_.ttf",
134
        ":ressources/__system/graphics/fonts/arialbd.ttf",
135
        ":ressources/__system/graphics/fonts/arial.ttf",
136
        ":ressources/__system/graphics/fonts/cour.ttf",
137
        ":ressources/__system/graphics/sounds/audioTest.wav",
138
        ":ressources/__system/graphics/sounds/docked.mp3",
139
        ":ressources/__system/graphics/sounds/doubleBeep01.wav",
140
        ":ressources/__system/graphics/sounds/doubleBeep02.wav",
141
        ":ressources/__system/graphics/sounds/doubleBeep03.wav",
142
        ":ressources/__system/graphics/sounds/doubleBeep04.wav",
143
        ":ressources/__system/graphics/sounds/doubleBeep05.wav",
144
        ":ressources/__system/graphics/sounds/doubleBeep06.wav",
145
        ":ressources/__system/graphics/sounds/doubleBeep07.wav",
146
        ":ressources/__system/graphics/sounds/doubleBeep08.wav",
147
        ":ressources/__system/graphics/sounds/doubleBeep09.wav",
148
        ":ressources/__system/graphics/sounds/doubleBeep10.wav",
149
        ":ressources/__system/graphics/sounds/doubleBeep.wav",
150
        ":ressources/__system/graphics/sounds/ringback.wav",
151
        ":ressources/__system/graphics/sounds/ringtone.wav",
152
        ":ressources/__system/graphics/sounds/singleBeep01.wav",
153
        ":ressources/__system/graphics/sounds/singleBeep02.wav",
154
        ":ressources/__system/graphics/sounds/singleBeep03.wav",
155
        ":ressources/__system/graphics/sounds/singleBeep04.wav",
156
        ":ressources/__system/graphics/sounds/singleBeep05.wav",
157
        ":ressources/__system/graphics/sounds/singleBeep06.wav",
158
        ":ressources/__system/graphics/sounds/singleBeep07.wav",
159
        ":ressources/__system/graphics/sounds/singleBeep08.wav",
160
        ":ressources/__system/graphics/sounds/singleBeep09.wav",
161
        ":ressources/__system/graphics/sounds/singleBeep10.wav",
162
        ":ressources/__system/graphics/sounds/singleBeep.wav",
163
        ":ressources/__system/graphics/draw.xma",
164
        ":ressources/__system/graphics/fnt.xma",
165
        ":ressources/__system/graphics/version.xma"
166
    };
167
 
168
    bool err = false;
169
    vector<string>::iterator iter;
170
 
171
    for (iter = resFiles.begin(); iter != resFiles.end(); ++iter)
172
    {
173
        if (!copyFile(*iter))
174
            err = true;
175
    }
176
 
177
    return err;
178
}
179
 
50 andreas 180
bool TTPInit::createDirectoryStructure()
181
{
182
    DECL_TRACER("TTPInit::createDirectoryStructure()");
183
 
51 andreas 184
    if (mPath.empty())
185
    {
186
        MSG_ERROR("Got no path to create the directory structure!");
187
        return false;
188
    }
189
 
50 andreas 190
    string pfad = mPath;
191
 
192
    if (!_makeDir(pfad))
193
        return false;
194
 
195
    pfad = mPath + "/fonts";
196
 
197
    if (!_makeDir(pfad))
198
        return false;
199
 
200
    pfad = mPath + "/images";
201
 
202
    if (!_makeDir(pfad))
203
        return false;
204
 
205
    pfad = mPath + "/sounds";
206
 
207
    if (!_makeDir(pfad))
208
        return false;
209
 
210
    pfad = mPath + "/__system";
211
 
212
    if (!_makeDir(pfad))
213
        return false;
214
 
215
    pfad = mPath + "/__system/graphics";
216
 
217
    if (!_makeDir(pfad))
218
        return false;
219
 
220
    pfad = mPath + "/__system/graphics/fonts";
221
 
222
    if (!_makeDir(pfad))
223
        return false;
224
 
225
    pfad = mPath + "/__system/graphics/images";
226
 
227
    if (!_makeDir(pfad))
228
        return false;
229
 
230
    pfad = mPath + "/__system/graphics/sounds";
231
 
232
    if (!_makeDir(pfad))
233
        return false;
234
 
235
    pfad = mPath + "/__system/graphics/cursors";
236
 
237
    if (!_makeDir(pfad))
238
        return false;
239
 
240
    pfad = mPath + "/__system/graphics/sliders";
241
 
242
    if (!_makeDir(pfad))
243
        return false;
244
 
88 andreas 245
    pfad = mPath + "/__system/graphics/borders";
246
 
247
    if (!_makeDir(pfad))
248
        return false;
249
 
50 andreas 250
    return true;
251
}
252
 
253
bool TTPInit::_makeDir(const std::string& dir)
254
{
255
    DECL_TRACER("TTPInit::_makeDir(const std::string& dir)");
256
 
257
    TValidateFile vf;
258
 
71 andreas 259
    if (!vf.isValidDir(dir))
50 andreas 260
    {
261
        if (mkdir (dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXG) != 0)
262
        {
263
            MSG_ERROR("Directory " << dir << ": " << strerror(errno));
264
            return false;
265
        }
266
    }
267
 
268
    return true;
269
}
270
 
113 andreas 271
bool TTPInit::copyFile(const std::string& fname)
272
{
273
    DECL_TRACER("TTPInit::copyFile(const std::string& fname)");
274
 
275
    bool err = false;
276
    QFile external(fname.c_str());
277
    size_t pos = fname.find_first_of("/");
278
    string bname;
279
 
280
    if (pos != string::npos)
281
        bname = fname.substr(pos);
282
    else
283
        bname = fname;
284
 
285
    if (external.exists())
286
    {
287
        QString path = mPath.c_str();
288
        path += bname.c_str();
118 andreas 289
        bname = path.toStdString();
113 andreas 290
 
118 andreas 291
        // If the target already exists we must delete it first.
292
        if (access(bname.data(), F_OK) == 0)
293
            remove(bname.data());
294
 
113 andreas 295
        if (!external.copy(path))
296
        {
43 andreas 297
#ifdef __ANDROID__
113 andreas 298
            if (!askPermissions())
299
            {
300
                MSG_ERROR("Could not copy \"" << bname << "\" to " << path.toStdString() << " because permission was denied!");
301
                err = true;
302
            }
303
            else if (!external.copy(path))
304
            {
305
                MSG_ERROR("Could not copy \"" << bname << "\" to " << path.toStdString());
306
                err = true;
307
            }
308
#else
309
            MSG_ERROR("Could not copy \"" << bname << "\" to " << path.toStdString());
310
            err = true;
311
#endif
312
        }
313
    }
314
    else
315
    {
316
        MSG_ERROR("File " << external.fileName().toStdString() << " doesn't exist!");
317
        err = true;
318
    }
319
 
320
    return err;
321
}
322
 
115 andreas 323
/**
324
 * This methods checks if there exists a previous downloaded TP4 file. If this
325
 * is the case, nothing happens.
326
 * If there is no previous downloaded file it checks if there is one on the
327
 * controller and downloads it if it exists. After successfull download the
328
 * file is unpacked.
329
 *
330
 * @return TRUE is returned when there was a file successfully downloaded and
331
 * unpacked. In any other case FALSE is returned.
332
 */
333
bool TTPInit::loadSurfaceFromController(bool force)
334
{
335
    DECL_TRACER("TTPInit::loadSurfaceFromController(bool force)");
336
 
337
    TFsfReader reader;
120 andreas 338
    reader.regCallbackProgress(bind(&TTPInit::progressCallback, this, std::placeholders::_1));
115 andreas 339
    string target = mPath + "/" + TConfig::getFtpSurface();
117 andreas 340
    size_t pos = 0;
115 andreas 341
 
117 andreas 342
    if ((pos = mPath.find_last_of("/")) != string::npos)
343
        target = mPath.substr(0, pos) + "/" + TConfig::getFtpSurface();
344
 
115 andreas 345
    if (!force)
346
    {
347
        QFile pan(target.c_str());
348
 
349
        if (pan.exists() || TConfig::getFtpDownloadTime() > 0)
350
            return false;
351
    }
352
 
120 andreas 353
    if (_processEvents)
354
        _processEvents();
355
 
119 andreas 356
    // To be sure the target directory tree is empty, we delete all files but
357
    // keep the system directories and their content, if they exist.
358
    dir::TDirectory dir;
359
 
360
    if (dir.exists(mPath))
361
    {
362
        dir.dropDir(mPath);
363
        dir.dropDir(mPath + "/fonts");
364
        dir.dropDir(mPath + "/images");
365
        dir.dropDir(mPath + "/sounds");
366
    }
367
 
115 andreas 368
    if (!reader.copyOverFTP(TConfig::getFtpSurface(), target))
369
        return false;
370
 
120 andreas 371
    if (_processEvents)
372
        _processEvents();
373
 
117 andreas 374
    if (!reader.unpack(target, mPath))
375
    {
376
        MSG_ERROR("Unpacking was not successfull.");
115 andreas 377
        return false;
117 andreas 378
    }
115 andreas 379
 
119 andreas 380
    if (!force || !dir.exists(mPath + "/__system"))
118 andreas 381
    {
382
        createDirectoryStructure();
383
        createSystemConfigs();
384
    }
385
 
120 andreas 386
    if (_processEvents)
387
        _processEvents();
388
 
119 andreas 389
    dir.dropFile(target);       // We remove our traces
115 andreas 390
    TConfig::saveFtpDownloadTime(time(NULL));
391
    TConfig::saveSettings();
392
    return true;
393
}
394
 
120 andreas 395
int TTPInit::progressCallback(off64_t xfer)
396
{
397
    DECL_TRACER("TTPInit::progressCallback(off64_t xfer)");
398
 
399
    if (_processEvents && xfer > 0)
400
        _processEvents();
401
 
402
    return 1;
403
}
404
 
113 andreas 405
#ifdef __ANDROID__
43 andreas 406
bool TTPInit::askPermissions()
407
{
115 andreas 408
    DECL_TRACER("TTPInit::askPermissions()");
43 andreas 409
 
410
    QStringList permissions = { "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE" };
411
    QtAndroid::PermissionResultMap perms = QtAndroid::requestPermissionsSync(permissions);
412
 
413
    for (auto iter = perms.begin(); iter != perms.end(); ++iter)
414
    {
415
        if (iter.value() == QtAndroid::PermissionResult::Denied)
416
            return false;
417
    }
418
 
419
    return true;
420
}
421
#endif