38#include <QDBusMessage>
73 static unsigned int session_counter = 0;
75 const unsigned int current_session = session_counter++;
80 QUuid::createUuid().toString(),
121 MH_ERROR() <<
"Failed to register MPRIS object";
143 return "/com/lomiri/MediaHub/Service/sessions/" + QString::number(key);
152 MH_ERROR(
"Requested adaptor for non-existing player %d", info.
key);
169 bool ok = adaptor->registerAt(info.
objectPath);
176 auto trackListAdaptor =
182 ok =
m_connection.registerObject(trackList->objectName(),
184 QDBusConnection::ExportAllSlots |
185 QDBusConnection::ExportScriptableSignals |
186 QDBusConnection::ExportAllProperties);
188 MH_ERROR(
"Failed to export TrackList for %d", info.
key);
206 if (!ok)
return false;
207 return impl->playerByKey(key) !=
nullptr;
226 QDBusMessage msg = message();
227 QDBusConnection bus = connection();
229 const auto sessionInfo = d->createSessionInfo();
232 MH_DEBUG(
"Session created by request of: %s, key: %d, uuid: %s",
233 qUtf8Printable(client.
name), client.
key, qUtf8Printable(sessionInfo.uuid));
237 d->impl->create_session(client);
238 d->uuid_player_map[sessionInfo.uuid] = client.
key;
240 d->request_context_resolver->resolve_context_for_dbus_name_async(client.
name,
243 Q_D(ServiceSkeleton);
244 MH_DEBUG(
" -- app_name='%s', attached", qUtf8Printable(context.str()));
245 d->player_owner_map[client.key] = OwnerInfo { context.str(), true, client.name };
247 }
catch(
const std::runtime_error& e)
255 d->exportPlayer(sessionInfo);
256 uuid = sessionInfo.uuid;
257 op = QDBusObjectPath(sessionInfo.objectPath);
266 if (!d->uuidIsValid(uuid, key))
return;
267 if (!d->player_owner_map.contains(key))
return;
269 auto &info = d->player_owner_map[key];
272 if (info.isAttached && info.serviceName == message().service()) {
273 info.isAttached =
false;
274 info.serviceName.clear();
276 auto player = d->impl->playerByKey(key);
279 }
catch(
const std::runtime_error& e)
291 if (!d->uuidIsValid(uuid, key)) {
297 QDBusObjectPath op(d->pathForPlayer(key));
299 QDBusMessage msg = message();
300 QDBusConnection bus = connection();
301 msg.setDelayedReply(
true);
305 d->request_context_resolver->resolve_context_for_dbus_name_async(msg.service(),
308 Q_D(ServiceSkeleton);
309 auto &info = d->player_owner_map[key];
310 MH_DEBUG(
" -- reattach app_name='%s', info='%s', '%s'",
311 qUtf8Printable(context.str()),
312 qUtf8Printable(info.profile),
313 qUtf8Printable(info.serviceName));
314 if (info.profile == context.str()) {
315 info.isAttached = true;
316 info.serviceName = msg.service();
319 PlayerImplementation *player = d->impl->playerByKey(key);
322 auto reply = msg.createReply();
323 reply << QVariant::fromValue(op);
328 auto reply = msg.createErrorReply(
329 mpris::Service::Errors::ReattachingSession::name(),
330 "Invalid permissions for the requested session");
335 }
catch(
const std::runtime_error& e)
348 if (!d->uuidIsValid(uuid, key)) {
356 QDBusMessage msg = message();
357 QDBusConnection bus = connection();
358 msg.setDelayedReply(
true);
360 d->request_context_resolver->resolve_context_for_dbus_name_async(msg.service(),
363 Q_D(ServiceSkeleton);
364 auto info = d->player_owner_map.value(key);
365 MH_DEBUG(
" -- Destroying app_name='%s', info='%s', '%s'",
366 qUtf8Printable(context.str()),
367 qUtf8Printable(info.profile),
368 qUtf8Printable(info.serviceName));
369 if (info.profile == context.str()) {
372 d->uuid_player_map.remove(uuid);
373 d->player_owner_map.remove(key);
376 PlayerImplementation *player = d->impl->playerByKey(key);
379 player->setLifetime(media::Player::Lifetime::normal);
382 bus.send(msg.createReply());
385 auto reply = msg.createErrorReply(
386 mpris::Service::Errors::DestroyingSession::name(),
387 "Invalid permissions for the requested session");
392 }
catch(
const std::runtime_error& e)
405 if (d->named_player_map.contains(name) == 0) {
407 auto sessionInfo = d->createSessionInfo();
409 QDBusMessage msg = message();
411 QDBusObjectPath op(sessionInfo.objectPath);
413 auto session = d->impl->create_session(client);
416 d->exportPlayer(sessionInfo);
417 d->named_player_map.insert(name, client.
key);
421 const auto player = d->named_player_map.contains(name) ?
422 d->impl->playerByKey(d->named_player_map[name]) :
nullptr;
426 "Unable to locate player session");
430 return QDBusObjectPath(d->pathForPlayer(player->key()));
432 }
catch(
const std::runtime_error& e)
446 auto player = d->impl->playerByKey(key);
449 "Unable to locate player session");
453 return QDBusObjectPath(d->pathForPlayer(key));
461 d->impl->pause_other_sessions(key);
463 catch (
const std::out_of_range &e) {
464 MH_WARNING(
"Failed to look up Player instance for key %d\
465 , no valid Player instance for that key value and cannot set current player.\
466 This most likely means that media-hub-server has crashed and restarted.", key);
469 "Player key not found");
QSharedPointer< RequestContextResolver > Ptr
static const QString & name()
static const QString & name()
static const QString & name()
static const QString & name()
static const QString & name()
static const QString & name()
static const QString & name()