1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2022 Konsulko Group
*/
#include <QDebug>
#include "AppLauncherGrpcClient.h"
#include "AppLauncherClient.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::ClientReader;
using grpc::Status;
using automotivegradelinux::AppLauncher;
using automotivegradelinux::StartRequest;
using automotivegradelinux::StartResponse;
using automotivegradelinux::ListRequest;
using automotivegradelinux::ListResponse;
using automotivegradelinux::AppInfo;
using automotivegradelinux::StatusRequest;
using automotivegradelinux::StatusResponse;
using automotivegradelinux::AppStatus;
void AppStatusEventReader::GetStatusEvents()
{
ClientContext context;
StatusRequest request;
StatusResponse response;
std::unique_ptr<ClientReader<StatusResponse> > reader(stub_->GetStatusEvents(&context, request));
while (reader->Read(&response)) {
if (response.has_app()) {
AppStatus app_status = response.app();
emit statusUpdate(QString::fromStdString(app_status.id()),
QString::fromStdString(app_status.status()));
}
}
Status status = reader->Finish();
if (!status.ok()) {
qWarning() << "GetStatusEvents RPC failed";
}
emit finished();
}
AppLauncherGrpcClient::AppLauncherGrpcClient(QObject *parent) : QObject(parent)
{
stub_ = AppLauncher::NewStub(grpc::CreateChannel("localhost:50052", grpc::InsecureChannelCredentials()));
// Create thread to read status events
AppStatusEventReader *reader = new AppStatusEventReader(stub_);
reader->moveToThread(&m_event_thread);
connect(&m_event_thread, &QThread::started, reader, &AppStatusEventReader::GetStatusEvents);
connect(reader, &AppStatusEventReader::finished, &m_event_thread, &QThread::quit);
// FIXME: Normally the thread finishing would be connected per the below
// to trigger cleaning up the object. That seems to trigger a crash
// for not entirely obvious reasons. It seems unrelated to the signal
// connection to AppLauncherClient, as not connecting does not prevent
// the crash; further investigation is required.
//connect(reader, &AppStatusEventReader::finished, reader, &AppStatusEventReader::deleteLater);
//connect(&m_event_thread, &QThread::finished, &m_event_thread, &QThread::deleteLater);
// To avoid having an intermediary slot+signal in this class, try
// casting parent to AppLauncherClient and connect directly to its
// slot. Callers should set parent to ensure this works as required.
if (parent) {
AppLauncherClient *launcher = qobject_cast<AppLauncherClient*>(parent);
if (launcher)
connect(reader,
&AppStatusEventReader::statusUpdate,
launcher,
&AppLauncherClient::sendStatusEvent);
}
// Start status event handling
m_event_thread.start();
}
bool AppLauncherGrpcClient::StartApplication(const QString &id)
{
StartRequest request;
request.set_id(id.toStdString());
ClientContext context;
StartResponse response;
Status status = stub_->StartApplication(&context, request, &response);
return status.ok();
}
bool AppLauncherGrpcClient::ListApplications(QList<QMap<QString, QString>> &list)
{
ListRequest request; // empty
ClientContext context;
ListResponse response;
Status status = stub_->ListApplications(&context, request, &response);
if (!status.ok())
return false;
for (int i = 0; i < response.apps_size(); i++) {
QMap<QString, QString> appinfo_map;
AppInfo appinfo = response.apps(i);
appinfo_map["id"] = QString::fromStdString(appinfo.id());
appinfo_map["name"] = QString::fromStdString(appinfo.name());
appinfo_map["icon_path"] = QString::fromStdString(appinfo.icon_path());
list.append(appinfo_map);
}
return true;
}
|