[client][linux] Use DBus to ensure single instance

This commit is contained in:
Abhishek Shroff
2026-02-14 10:51:20 +05:30
parent 1774b7648a
commit 7e77c81b36
3 changed files with 72 additions and 1 deletions

View File

@@ -1,3 +1,6 @@
import 'dart:io';
import 'package:dbus/dbus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
@@ -24,6 +27,40 @@ class _PhylumAppState extends State<PhylumApp> {
final PhylumRouterDelegate routerDelegate = PhylumRouterDelegate(builder: (context) => const AccountSelector());
final AccountManager<PhylumAccount> accountManager = createAccountManager(isPrimary());
@override
void initState() {
super.initState();
if (defaultTargetPlatform == TargetPlatform.linux) {
startDBusClient();
}
}
void startDBusClient() async {
final sessionClient = DBusClient.session();
final requestReply =
await sessionClient.requestName('cloud.phylum.drive.Instance', flags: {DBusRequestNameFlag.doNotQueue});
if (requestReply == DBusRequestNameReply.primaryOwner) {
await sessionClient.registerObject(InstanceObject());
} else if (requestReply == DBusRequestNameReply.exists) {
print('Instance Already Running');
final object = DBusRemoteObject(
sessionClient,
name: 'cloud.phylum.drive.Instance',
path: DBusObjectPath('/drive/phylum/cloud/Instance/Object'),
);
var value = await object.getProperty('cloud.phylum.drive.Instance', 'Version', signature: DBusSignature('s'));
var version = value.asString();
print('Version $version');
await object.callMethod('cloud.phylum.drive.Instance', 'Show', [], replySignature: DBusSignature(''));
await sessionClient.close();
exit(0);
} else {
throw StateError('Unsupported DBus Name Request Reply: $requestReply');
}
}
@override
Widget build(BuildContext context) {
return MultiProvider(
@@ -64,3 +101,36 @@ class _PhylumAppState extends State<PhylumApp> {
});
}
}
class InstanceObject extends DBusObject {
InstanceObject() : super(DBusObjectPath('/drive/phylum/cloud/Instance/Object'));
@override
Future<DBusMethodResponse> getProperty(String interface, String name) async {
if (interface == 'cloud.phylum.drive.Instance') {
if (name == 'Version') {
return DBusGetPropertyResponse(DBusString('0.7'));
} else {
return DBusMethodErrorResponse.unknownProperty();
}
} else {
return DBusMethodErrorResponse.unknownInterface();
}
}
@override
Future<DBusMethodResponse> handleMethodCall(DBusMethodCall methodCall) async {
if (methodCall.interface == 'cloud.phylum.drive.Instance') {
if (methodCall.name == 'Show') {
if (methodCall.signature != DBusSignature('')) {
return DBusMethodErrorResponse.invalidArgs();
}
return DBusMethodSuccessResponse([]);
} else {
return DBusMethodErrorResponse.unknownMethod();
}
} else {
return DBusMethodErrorResponse.unknownInterface();
}
}
}

View File

@@ -226,7 +226,7 @@ packages:
source: hosted
version: "3.1.3"
dbus:
dependency: transitive
dependency: "direct main"
description:
name: dbus
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"

View File

@@ -15,6 +15,7 @@ dependencies:
cached_network_image_platform_interface:
circular_profile_avatar:
collection:
dbus:
device_info_plus: ^11.5.0
drift: ^2.19.1+1
drift_flutter: ^0.2.1