-
Notifications
You must be signed in to change notification settings - Fork 7
ayatana-indicator-bluetooth: Add Bluetooth pairing agent #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
muhammad23012009
wants to merge
6
commits into
AyatanaIndicators:main
Choose a base branch
from
muhammad23012009:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
5b45748
ayatana-indicator-bluetooth: add initial pairing agent
muhammad23012009 568f6aa
agent: use signals to register agent to BlueZ
muhammad23012009 6c7c62d
agent: Add support for PIN and passkeys on Lomiri
muhammad23012009 36d7794
agent: add proper support for AuthorizeService
muhammad23012009 ebefa98
agent: rename passkey to PIN
muhammad23012009 8e66b30
agent: translate strings
muhammad23012009 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| [DBus (name = "org.bluez.Agent1")] | ||
| public class Agent: Object | ||
| { | ||
| public GLib.Menu menu; | ||
| public GLib.SimpleActionGroup actions; | ||
| private GLib.SimpleAction pin_action; | ||
| public string menu_path; | ||
| public string actions_path; | ||
|
|
||
| private MainLoop loop; | ||
| private Bluetooth bluetooth; | ||
| private Notify.Notification? notification; | ||
| private string passkey; | ||
|
|
||
| public Agent (Bluetooth bluez) | ||
| { | ||
| // Menu | ||
| menu = new GLib.Menu (); | ||
| GLib.MenuItem item = new GLib.MenuItem ("", "notifications.pin"); | ||
| item.set_attribute_value ("x-canonical-type", new Variant.string ("com.canonical.snapdecision.textfield")); | ||
| item.set_attribute_value ("x-echo-mode-password", new Variant.boolean (false)); | ||
| menu.append_item (item); | ||
|
|
||
| // Actions | ||
| actions = new GLib.SimpleActionGroup (); | ||
| pin_action = new GLib.SimpleAction.stateful ("pin", null, new Variant.string ("")); | ||
| pin_action.change_state.connect ((value) => { | ||
| this.passkey = value.get_string (); | ||
| }); | ||
| actions.add_action (pin_action); | ||
|
|
||
| loop = new MainLoop (null, false); | ||
| bluetooth = bluez; | ||
| Notify.init ("ayatana-indicator-bluetooth"); | ||
| } | ||
|
|
||
| /* TODO: Add a better way to differentiate between rejected and cancelled errors, maybe with an enum */ | ||
| private bool sendNotification (string device_name, string body, bool need_input, bool have_actions) | ||
| { | ||
| bool accepted = !have_actions; | ||
|
|
||
| notification = new Notify.Notification (@"Pair with $device_name?", body, "bluetooth-active"); | ||
| notification.closed.connect (() => { | ||
| accepted = false; | ||
| notification = null; | ||
|
|
||
| if (loop.is_running ()) { | ||
| loop.quit (); | ||
| } | ||
| }); | ||
|
|
||
| bool is_lomiri = AyatanaCommon.utils_is_lomiri (); | ||
|
|
||
| if (is_lomiri) { | ||
| if (have_actions) { | ||
| notification.set_hint ("x-lomiri-snap-decisions", true); | ||
| notification.set_hint ("x-lomiri-private-affirmative-tint", "true"); | ||
| } | ||
|
|
||
| if (need_input) { | ||
| VariantBuilder actions_builder = new VariantBuilder (new VariantType ("a{sv}")); | ||
| actions_builder.add ("{sv}", "notifications", new Variant.string (actions_path)); | ||
|
|
||
| VariantBuilder builder = new VariantBuilder (new VariantType ("a{sv}")); | ||
| builder.add ("{sv}", "busName", new Variant.string ("org.ayatana.indicator.bluetooth")); | ||
| builder.add ("{sv}", "menuPath", new Variant.string (menu_path)); | ||
| builder.add ("{sv}", "actions", actions_builder.end ()); | ||
|
|
||
| notification.set_hint ("x-lomiri-private-menu-model", builder.end ()); | ||
| } | ||
| } | ||
|
|
||
| if (have_actions) { | ||
| notification.add_action("yes_id", "Yes", (notif, action) => { | ||
| loop.quit (); | ||
| notification = null; | ||
| accepted = true; | ||
| }); | ||
| notification.add_action("no_id", "No", (notif, action) => { | ||
| loop.quit (); | ||
| notification = null; | ||
| accepted = false; | ||
| }); | ||
| } | ||
|
|
||
| if (!have_actions && !need_input) { | ||
| // Display-only notification. Make sure we don't time out. | ||
| notification.set_hint ("urgency", 2); | ||
| } | ||
|
|
||
| try { | ||
| notification.show (); | ||
| } | ||
| catch (Error e) { | ||
| warning ("Panic: Failed showing notification: %s", e.message); | ||
| } | ||
|
|
||
| if (have_actions) { | ||
| loop.run (); | ||
| } | ||
|
|
||
| return accepted; | ||
| } | ||
|
|
||
| public void AuthorizeService (GLib.ObjectPath object, string uuid) throws GLib.DBusError, GLib.IOError | ||
| { | ||
| } | ||
muhammad23012009 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| public void RequestConfirmation (GLib.ObjectPath object, uint32 passkey) throws RejectedError, GLib.DBusError, GLib.IOError | ||
| { | ||
| string body = "Are you sure you want to pair with passkey %06u?".printf (passkey); | ||
muhammad23012009 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| bool confirmed = sendNotification (bluetooth.get_device_name (object), body, false, true); | ||
|
|
||
| if (!confirmed) { | ||
| throw new RejectedError.ERROR ("Rejected by user"); | ||
| } | ||
| } | ||
|
|
||
| public void RequestAuthorization (GLib.ObjectPath object) throws RejectedError, GLib.DBusError, GLib.IOError | ||
| { | ||
| bool authorized = sendNotification (bluetooth.get_device_name (object), "Are you sure you want to pair with this device?", false, true); | ||
|
|
||
| if (!authorized) { | ||
| throw new RejectedError.ERROR ("Rejected by user"); | ||
| } | ||
| } | ||
|
|
||
| public string RequestPinCode (GLib.ObjectPath object) throws RejectedError, GLib.DBusError, GLib.IOError | ||
| { | ||
| bool accepted = sendNotification (bluetooth.get_device_name (object), "Enter PIN for this device", true, true); | ||
|
|
||
| if (!accepted) { | ||
| throw new RejectedError.ERROR ("Rejected by user"); | ||
| } | ||
|
|
||
| return passkey; | ||
| } | ||
|
|
||
| public void DisplayPinCode (GLib.ObjectPath object, string pincode) throws GLib.DBusError, GLib.IOError | ||
| { | ||
| sendNotification (bluetooth.get_device_name (object), @"Enter the PIN code $pincode on the other device", false, false); | ||
| } | ||
|
|
||
| public uint32 RequestPasskey (GLib.ObjectPath object) throws RejectedError, GLib.DBusError, GLib.IOError | ||
| { | ||
| bool accepted = sendNotification (bluetooth.get_device_name (object), "Enter passkey for this device", true, true); | ||
|
|
||
| if (!accepted) { | ||
| throw new RejectedError.ERROR ("Rejected by user"); | ||
| } | ||
|
|
||
| return passkey.to_int (); | ||
| } | ||
|
|
||
| public void DisplayPasskey (GLib.ObjectPath object, uint32 passkey, uint16 entered) throws GLib.DBusError, GLib.IOError | ||
| { | ||
| string body = "Enter the passkey %06u on the other device".printf (passkey); | ||
| sendNotification (bluetooth.get_device_name (object), body, false, false); | ||
| } | ||
|
|
||
| public void Cancel () throws GLib.DBusError, GLib.IOError | ||
| { | ||
| if (loop.is_running ()) { | ||
| loop.quit (); | ||
| } | ||
|
|
||
| if (notification != null) { | ||
| notification.close (); | ||
| notification = null; | ||
| } | ||
| } | ||
|
|
||
| public void Release () throws GLib.DBusError, GLib.IOError | ||
| { | ||
| } | ||
| } | ||
|
|
||
| [DBus (name = "org.bluez.Error.Cancelled")] | ||
| public errordomain CancelledError { | ||
| ERROR | ||
| } | ||
|
|
||
| [DBus (name = "org.bluez.Error.Rejected")] | ||
| public errordomain RejectedError { | ||
| ERROR | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.