diff --git a/po/POTFILES b/po/POTFILES index c2204094..10a5cb8b 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,6 +1,5 @@ src/Plug.vala src/MainView.vala -src/PairDialog.vala src/DeviceRow.vala src/Services/Manager.vala src/Services/Device.vala diff --git a/src/PairDialog.vala b/src/PairDialog.vala deleted file mode 100644 index d061cc51..00000000 --- a/src/PairDialog.vala +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 2018 elementary LLC. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -public class PairDialog : Granite.MessageDialog { - public enum AuthType { - REQUEST_CONFIRMATION, - REQUEST_AUTHORIZATION, - DISPLAY_PASSKEY, - DISPLAY_PIN_CODE - } - - public ObjectPath object_path { get; construct; } - public AuthType auth_type { get; construct; } - public string passkey { get; construct; } - public bool cancelled { get; set; } - - // Un-used default constructor - private PairDialog () { - Object ( - buttons: Gtk.ButtonsType.CANCEL - ); - } - - public PairDialog.request_authorization (ObjectPath object_path, Gtk.Window? main_window) { - Object ( - auth_type: AuthType.REQUEST_AUTHORIZATION, - buttons: Gtk.ButtonsType.CANCEL, - object_path: object_path, - primary_text: _("Confirm Bluetooth Pairing"), - transient_for: main_window - ); - } - - public PairDialog.display_passkey (ObjectPath object_path, uint32 passkey, uint16 entered, Gtk.Window? main_window) { - Object ( - auth_type: AuthType.DISPLAY_PASSKEY, - buttons: Gtk.ButtonsType.CANCEL, - object_path: object_path, - passkey: "%u".printf (passkey), - primary_text: _("Confirm Bluetooth Passkey"), - transient_for: main_window - ); - } - - public PairDialog.request_confirmation (ObjectPath object_path, uint32 passkey, Gtk.Window? main_window) { - Object ( - auth_type: AuthType.REQUEST_CONFIRMATION, - buttons: Gtk.ButtonsType.CANCEL, - object_path: object_path, - passkey: "%u".printf (passkey), - primary_text: _("Confirm Bluetooth Passkey"), - transient_for: main_window - ); - } - - public PairDialog.display_pin_code (ObjectPath object_path, string pincode, Gtk.Window? main_window) { - Object ( - auth_type: AuthType.DISPLAY_PIN_CODE, - buttons: Gtk.ButtonsType.CANCEL, - object_path: object_path, - passkey: pincode, - primary_text: _("Enter Bluetooth PIN"), - transient_for: main_window - ); - } - - construct { - Bluetooth.Services.Device device; - string device_name = _("Unknown Bluetooth Device"); - try { - device = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", object_path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES); - image_icon = new ThemedIcon (device.icon ?? "bluetooth"); - device_name = device.name ?? device.address; - } catch (IOError e) { - image_icon = new ThemedIcon ("bluetooth"); - critical (e.message); - } - - switch (auth_type) { - case AuthType.REQUEST_CONFIRMATION: - badge_icon = new ThemedIcon ("dialog-password"); - secondary_text = _("Make sure the code displayed on “%s” matches the one below.").printf (device_name); - - var confirm_button = add_button (_("Pair"), Gtk.ResponseType.ACCEPT); - confirm_button.get_style_context ().add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); - break; - case AuthType.DISPLAY_PASSKEY: - badge_icon = new ThemedIcon ("dialog-password"); - secondary_text = _("“%s” would like to pair with this device. Make sure the code displayed on “%s” matches the one below.").printf (device_name, device_name); - - var confirm_button = add_button (_("Pair"), Gtk.ResponseType.ACCEPT); - confirm_button.get_style_context ().add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); - break; - case AuthType.DISPLAY_PIN_CODE: - badge_icon = new ThemedIcon ("dialog-password"); - secondary_text = _("Type the code displayed below on “%s”, followed by Enter.").printf (device_name); - break; - case AuthType.REQUEST_AUTHORIZATION: - badge_icon = new ThemedIcon ("dialog-question"); - secondary_text = _("“%s” would like to pair with this device.").printf (device_name); - - var confirm_button = add_button (_("Pair"), Gtk.ResponseType.ACCEPT); - confirm_button.get_style_context ().add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); - break; - } - - if (passkey != null && passkey != "") { - var passkey_label = new Gtk.Label (passkey); - passkey_label.get_style_context ().add_class (Granite.STYLE_CLASS_H1_LABEL); - - custom_bin.append (passkey_label); - } - - modal = true; - } -} diff --git a/src/Plug.vala b/src/Plug.vala index e7668452..342e8594 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -62,13 +62,11 @@ public class Bluetooth.Plug : Switchboard.Plug { } public override void shown () { - manager.register_agent.begin (main_view.get_root () as Gtk.Window); manager.set_global_state.begin (true); /* Also sets discoverable true and starts discovery */ } public override void hidden () { Application.get_default ().hold (); - manager.unregister_agent.begin (); manager.discoverable = false; /* Does not change is_powered or connections*/ manager.stop_discovery.begin (() => { Application.get_default ().release (); diff --git a/src/Services/Agent.vala b/src/Services/Agent.vala deleted file mode 100644 index 17762432..00000000 --- a/src/Services/Agent.vala +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * Copyright (c) 2018 elementary LLC. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Authored by: Corentin Noël - */ - -[DBus (name = "org.bluez.Error")] -public errordomain BluezError { - REJECTED, - CANCELED -} - -[DBus (name = "org.bluez.Agent1")] -public class Bluetooth.Services.Agent : Object { - private const string PATH = "/org/bluez/agent/elementary"; - Gtk.Window? main_window; - - private PairDialog pair_dialog; - - [DBus (visible=false)] - public Agent (Gtk.Window? main_window) { - this.main_window = main_window; - Bus.own_name (BusType.SYSTEM, "org.bluez.AgentManager1", BusNameOwnerFlags.NONE, - (connection, name) => { - try { - connection.register_object (PATH, this); - ready = true; - } catch (Error e) { - critical (e.message); - } - }, - (connection, name) => {}, - (connection, name) => {} - ); - } - - [DBus (visible=false)] - public bool ready { get; private set; } - - [DBus (visible=false)] - public signal void unregistered (); - - [DBus (visible=false)] - public GLib.ObjectPath get_path () { - return new GLib.ObjectPath (PATH); - } - - public void release () throws Error { - unregistered (); - } - - public async string request_pin_code (ObjectPath device) throws Error, BluezError { - throw new BluezError.REJECTED ("Pairing method not supported"); - } - - // Called to display a pin code on-screen that needs to be entered on the other device. Can return - // instantly - public async void display_pin_code (ObjectPath device, string pincode) throws Error, BluezError { - pair_dialog = new PairDialog.display_pin_code (device, pincode, main_window); - pair_dialog.present (); - } - - public async uint32 request_passkey (ObjectPath device) throws Error, BluezError { - throw new BluezError.REJECTED ("Pairing method not supported"); - } - - // Called to display a passkey on-screen that needs to be entered on the other device. Can return - // instantly - public async void display_passkey (ObjectPath device, uint32 passkey, uint16 entered) throws Error { - pair_dialog = new PairDialog.display_passkey (device, passkey, entered, main_window); - pair_dialog.present (); - } - - // Called to request confirmation from the user that they want to pair with the given device and that - // the passkey matches. **MUST** throw BluezError if pairing is to be rejected. This is handled in - // `check_pairing_response`. If the method returns without an error, pairing is authorized - public async void request_confirmation (ObjectPath device, uint32 passkey) throws Error, BluezError { - pair_dialog = new PairDialog.request_confirmation (device, passkey, main_window); - yield check_pairing_response (pair_dialog); - } - - // Called to request confirmation from the user that they want to pair with the given device - // **MUST** throw BluezError if pairing is to be rejected. This is handled in `check_pairing_response` - // If the method returns without an error, pairing is authorized - public async void request_authorization (ObjectPath device) throws Error, BluezError { - pair_dialog = new PairDialog.request_authorization (device, main_window); - yield check_pairing_response (pair_dialog); - } - - // Called to authorize the use of a specific service (Audio/HID/etc), so we restrict this to paired - // devices only - public void authorize_service (ObjectPath device_path, string uuid) throws Error, BluezError { - var device = get_device_from_object_path (device_path); - - bool paired = device.paired; - bool trusted = device.trusted; - - // Shouldn't really happen as trusted devices should be automatically authorized, but lets handle it anyway - if (paired && trusted) { - // allow - return; - } - - // A device that has been paired, but not yet trusted, trust it and allow it to access - // services - if (paired && !trusted) { - device.trusted = true; - // allow - return; - } - - // Reject everything else - throw new BluezError.REJECTED ("Rejecting service auth, not paired or trusted"); - } - - public void cancel () throws Error { - if (pair_dialog != null) { - pair_dialog.cancelled = true; - pair_dialog.destroy (); - } - } - - private async void check_pairing_response (PairDialog dialog) throws BluezError { - SourceFunc callback = check_pairing_response.callback; - BluezError? error = null; - - dialog.response.connect ((response) => { - if (response != Gtk.ResponseType.ACCEPT || dialog.cancelled) { - if (dialog.cancelled) { - error = new BluezError.CANCELED ("Pairing cancelled"); - } else { - error = new BluezError.REJECTED ("Pairing rejected"); - } - } - - Idle.add ((owned)callback); - dialog.destroy (); - }); - - dialog.present (); - - yield; - - if (error != null) { - throw error; - } - } - - private Device get_device_from_object_path (ObjectPath object_path) throws GLib.Error { - return Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", object_path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES); - } -} diff --git a/src/Services/Manager.vala b/src/Services/Manager.vala index db340346..1d07c5b0 100644 --- a/src/Services/Manager.vala +++ b/src/Services/Manager.vala @@ -18,13 +18,6 @@ * Authored by: Corentin Noël */ -[DBus (name = "org.bluez.AgentManager1")] -public interface Bluetooth.Services.AgentManager : Object { - public abstract void register_agent (ObjectPath agent, string capability) throws Error; - public abstract void request_default_agent (ObjectPath agent) throws Error; - public abstract void unregister_agent (ObjectPath agent) throws Error; -} - public class Bluetooth.Services.ObjectManager : Object { private const string SCHEMA = "io.elementary.desktop.wingpanel.bluetooth"; public signal void adapter_added (Bluetooth.Services.Adapter adapter); @@ -40,12 +33,8 @@ public class Bluetooth.Services.ObjectManager : Object { public bool is_powered {get; private set; default = false; } public bool is_connected {get; private set; default = false; } - private bool is_registered = false; - private Settings? settings = null; private GLib.DBusObjectManagerClient object_manager; - private Bluetooth.Services.AgentManager agent_manager; - private Bluetooth.Services.Agent agent; construct { var settings_schema = SettingsSchemaSource.get_default ().lookup (SCHEMA, true); @@ -97,9 +86,6 @@ public class Bluetooth.Services.ObjectManager : Object { [CCode (cname="bluetooth_services_adapter_proxy_get_type")] extern static GLib.Type get_adapter_proxy_type (); - [CCode (cname="bluetooth_services_agent_manager_proxy_get_type")] - extern static GLib.Type get_agent_manager_proxy_type (); - private GLib.Type object_manager_proxy_get_type (DBusObjectManagerClient manager, string object_path, string? interface_name) { if (interface_name == null) return typeof (GLib.DBusObjectProxy); @@ -109,8 +95,6 @@ public class Bluetooth.Services.ObjectManager : Object { return get_device_proxy_type (); case "org.bluez.Adapter1": return get_adapter_proxy_type (); - case "org.bluez.AgentManager1": - return get_agent_manager_proxy_type (); default: return typeof (GLib.DBusProxy); } @@ -239,54 +223,6 @@ public class Bluetooth.Services.ObjectManager : Object { return null; } - private async void create_agent (Gtk.Window? window) { - if (object_manager == null) { - return; - } - GLib.DBusObject? bluez_object = object_manager.get_object ("/org/bluez"); - if (bluez_object != null) { - agent_manager = (Bluetooth.Services.AgentManager) bluez_object.get_interface ("org.bluez.AgentManager1"); - } - - agent = new Bluetooth.Services.Agent (window); - agent.notify["ready"].connect (() => { - if (is_registered) { - register_agent.begin (window); - } - }); - - agent.unregistered.connect (() => { - is_registered = false; - }); - } - - public async void register_agent (Gtk.Window? window) { - is_registered = true; - if (agent_manager == null) { - yield create_agent (window); - } - - if (agent_manager != null && agent.ready) { - try { - agent_manager.register_agent (agent.get_path (), "DisplayYesNo"); - agent_manager.request_default_agent (agent.get_path ()); - } catch (Error e) { - critical (e.message); - } - } - } - - public async void unregister_agent () { - is_registered = false; - if (agent_manager != null && agent.ready) { - try { - agent_manager.unregister_agent (agent.get_path ()); - } catch (Error e) { - critical (e.message); - } - } - } - public void check_global_state () { /* As this is called within a signal handler and emits a signal * it should be in a Idle loop else races occur */ diff --git a/src/meson.build b/src/meson.build index c3baf651..db7f07f7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,9 +1,7 @@ plug_files = files( - 'PairDialog.vala', 'Plug.vala', 'MainView.vala', 'DeviceRow.vala', - 'Services/Agent.vala', 'Services/Manager.vala', 'Services/Device.vala', 'Services/Adapter.vala'