From a6b69401438c9949486d961d94357c41977cccfe Mon Sep 17 00:00:00 2001 From: meizhigang Date: Tue, 15 Aug 2023 20:52:36 +0800 Subject: [PATCH] fix(accounts):Fix user icon file display while change and login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 适配在更改用户图标后切换登录 Related #12711 --- plugins/accounts/user.cpp | 81 +++++++++++++++++++++++++++++++++++---- plugins/accounts/user.h | 7 +++- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/plugins/accounts/user.cpp b/plugins/accounts/user.cpp index b0ad852..6c9864b 100644 --- a/plugins/accounts/user.cpp +++ b/plugins/accounts/user.cpp @@ -33,7 +33,12 @@ namespace Kiran { #define USERDIR "/var/lib/AccountsService/users" #define ICONDIR "/var/lib/AccountsService/icons" -#define ACCOUNTS_USER_OBJECT_PATH "/com/kylinsec/Kiran/SystemDaemon/Accounts/User" +#define KIRAN_ACCOUNTS_USER_OBJECT_PATH "/com/kylinsec/Kiran/SystemDaemon/Accounts/User" + +#define FREEDESKTOP_ACCOUNTS_DBUS_NAME "org.freedesktop.Accounts" +#define FREEDESKTOP_ACCOUNTS_OBJECT_PATH "/org/freedesktop/Accounts" +#define FREEDESKTOP_ACCOUNTS_DBUS_INTERFACE "org.freedesktop.Accounts" +#define FREEDESKTOP_ACCOUNTS_USER_DBUS_INTERFACE "org.freedesktop.Accounts.User" User::User(PasswdShadow passwd_shadow) : passwd_shadow_(passwd_shadow), object_register_id_(0), @@ -62,7 +67,7 @@ std::shared_ptr User::create_user(PasswdShadow passwd_shadow) void User::dbus_register() { KLOG_PROFILE("Uid: %" PRIu64, this->uid_); - this->object_path_ = fmt::format(ACCOUNTS_USER_OBJECT_PATH "/{0}", this->uid_get()); + this->object_path_ = fmt::format(KIRAN_ACCOUNTS_USER_OBJECT_PATH "/{0}", this->uid_get()); try { this->dbus_connect_ = Gio::DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SYSTEM); @@ -298,6 +303,7 @@ void User::GetAuthItems(gint32 mode, MethodInvocation &invocation) void User::init() { + this->build_freedesktop_user_object_path(); this->udpate_nocache_var(this->passwd_shadow_); this->user_cache_ = std::make_shared(this->shared_from_this()); // 由于图标路径是维护在缓存中,所以必须等UserCache对象创建后才能操作 @@ -631,6 +637,7 @@ void User::change_icon_file_authorized_cb(MethodInvocation invocation, const Gli } while (0); this->icon_file_set(filename); + this->sync_icon_file_to_freedesktop(filename); invocation.ret(); } @@ -974,12 +981,6 @@ USER_PROP_SET_HANDLER(automatic_login, bool); USER_PROP_SET_HANDLER(system_account, bool); USER_PROP_SET_HANDLER(password_expiration_policy, const Glib::ustring &); -bool User::icon_file_changed(const Glib::ustring &value) -{ - this->icon_file_set(value); - return false; -} - AccountsAccountType User::account_type_from_pwent(std::shared_ptr passwd) { g_return_val_if_fail(passwd, AccountsAccountType::ACCOUNTS_ACCOUNT_TYPE_STANDARD); @@ -1023,6 +1024,7 @@ void User::reset_icon_file() if (icon_file != this->default_icon_file_) { this->icon_file_set(this->default_icon_file_); + this->sync_icon_file_to_freedesktop(this->default_icon_file_); } } } @@ -1034,4 +1036,67 @@ void User::move_extra_data(const std::string &old_name, const std::string &new_n g_rename(old_filename.c_str(), new_filename.c_str()); } +void User::build_freedesktop_user_object_path() +{ + this->freedesktop_object_path_ = Glib::DBusObjectPathString(); + + Glib::RefPtr account_proxy; + try + { + account_proxy = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SYSTEM, + FREEDESKTOP_ACCOUNTS_DBUS_NAME, + FREEDESKTOP_ACCOUNTS_OBJECT_PATH, + FREEDESKTOP_ACCOUNTS_DBUS_INTERFACE); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("%s", e.what().c_str()); + return; + } + + auto parameters = g_variant_new("(x)", this->uid_get()); + Glib::VariantContainerBase base(parameters, false); + try + { + auto retval = account_proxy->call_sync("FindUserById", base); + auto v1 = retval.get_child(0); + this->freedesktop_object_path_ = Glib::VariantBase::cast_dynamic>(v1).get().raw(); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("%s", e.what().c_str()); + } +} + +void User::sync_icon_file_to_freedesktop(const Glib::ustring &icon_file) +{ + RETURN_IF_TRUE(this->freedesktop_object_path_.empty()); + + Glib::RefPtr account_proxy; + try + { + account_proxy = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SYSTEM, + FREEDESKTOP_ACCOUNTS_DBUS_NAME, + this->freedesktop_object_path_, + FREEDESKTOP_ACCOUNTS_USER_DBUS_INTERFACE); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("%s", e.what().c_str()); + return; + } + + auto parameters = g_variant_new("(s)", icon_file.c_str()); + Glib::VariantContainerBase base(parameters, false); + Glib::VariantContainerBase retval; + try + { + retval = account_proxy->call_sync("SetIconFile", base); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("%s", e.what().c_str()); + } +} + } // namespace Kiran \ No newline at end of file diff --git a/plugins/accounts/user.h b/plugins/accounts/user.h index f467cd5..5915504 100644 --- a/plugins/accounts/user.h +++ b/plugins/accounts/user.h @@ -208,12 +208,16 @@ private: // 模式转为对应的keyfile的group_name std::string mode_to_groupname(int32_t mode); - bool icon_file_changed(const Glib::ustring &value); AccountsAccountType account_type_from_pwent(std::shared_ptr passwd); void reset_icon_file(); void move_extra_data(const std::string &old_name, const std::string &new_name); + void build_freedesktop_user_object_path(); + + // 由于切换用户时,登陆器通过org.freedesktop.Accounts接口获取图标,Kiran设置/更新用户图标后需要同步到freedesktop + void sync_icon_file_to_freedesktop(const Glib::ustring &icon_file); + private: private: Glib::RefPtr dbus_connect_; @@ -224,6 +228,7 @@ private: uint32_t object_register_id_; Glib::DBusObjectPathString object_path_; + Glib::DBusObjectPathString freedesktop_object_path_; std::string default_icon_file_; std::shared_ptr passwd_; -- 2.27.0