Compare commits

..

505 Commits

Author SHA1 Message Date
openvela-robot 81bfb81dc7 update workflow files 2026-02-02 19:42:26 +08:00
openvela-robot ab059a1a6f update .github 2026-01-04 10:59:19 +08:00
openvela-robot 4d574f5114 update .github 2026-01-04 10:59:19 +08:00
openvela-robot 27eaec3a64 update workflows ci.yml, delete pull_request_review trigger 2026-01-04 10:59:19 +08:00
openvela-robot da7dce2276 add .github/CODEOWNERS PULL_REQUEST_TEMPLATE.md 2026-01-04 10:59:19 +08:00
liujinye f168d0a538 delete gdbus 2025-12-29 13:18:48 +08:00
openvela-robot 11f44f733a add .github .gitee 2025-12-17 01:21:36 +08:00
yintao 6b596e4ff5 kvdb: Set the maximum listening count for kvdb separately
kvdbd is single threaded.
If CP calls property_list, AP'S kvdbd will continue to send to cp,
then accept will not be executed.
If another thread at CP loops to call property_set,
the AP server-side's pending queue will be full and reject next connection.

Bluetooth now loops through 15 times to call 'property_set',
So to avoid rejecting the connection,
set a macro to separately manage the listening count of kvdb

Signed-off-by: yintao <yintao@xiaomi.com>
2025-12-15 18:24:20 +08:00
ligd 9d294a428a kvdb: enhance server fault tolerance
When server recv msg header, there maybe recv only one byte.
Then we should continue the full header use kvdb_recv()

Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:20 +08:00
zhangbo56 5b2a21530c kvdb: Support kvdb server identified by device
Should be passed from device specific setting.

Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:20 +08:00
zhangbo56 33af11c421 kvdb: Export include/utils to other android module
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:20 +08:00
zhangbo56 4e1f285645 kvdb: Add kernel module headers to kvdb build
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:20 +08:00
huangcaihua b14b9c389c gdbus:Fix coverty for check return of asprintf
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:20 +08:00
huangcaihua e2311361b8 Fix coverity for return value check
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:20 +08:00
huangcaihua fc8cd0c944 Fix coverity for mistake free dbus watcher
Only free just alloced data variable here. No need call filter_data_free which maybe free watcher.

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:20 +08:00
huangcaihua 8617569b6b Fix coverity for FORWARD_NULL
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:20 +08:00
huangcaihua e5b7998e75 gdbus:Add new gdbus config with depend on uv-ext
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua 81bf130027 Fix: Compile warning and memory leak
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua ba9f08a713 refactor object file for open vela
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua a7d2c908d3 refactor watch file for open source
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua 68316d5269 refactor polkit file for open source
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
hongfengchen 78c43330e9 utils:KVDB_NVS should depend on MTD_CONFIG_NAMED
KVDB_NVS should depend on MTD_CONFIG_NAMED. If choose
select MTD_CONFIG_NAMED and CONFIG_MTD is not set, it
will lead to compile error like:

dev-system/nuttx/include/nuttx/mtd/configdata.h:79:20: error: 'CONFIG_MTD_CONFIG_NAME_LEN' undeclared here (not in a function); did you mean 'CONFIG_MTD_CONFIG_NAMED'?
   79 |   char        name[CONFIG_MTD_CONFIG_NAME_LEN];
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
      |                    CONFIG_MTD_CONFIG_NAMED

Signed-off-by: hongfengchen <hongfengchen@xiaomi.com>
2025-12-15 18:24:19 +08:00
wangxuedong ac19b907f1 kvdb: add retry if recv's errno is EAGAIN
Signed-off-by: wangxuedong <wangxuedong@xiaomi.com>
2025-12-15 18:24:19 +08:00
wushenhui 56d9f4f858 utils/kvdb: fix build error when CONFIG_NET_LOCAL not set and CONFIG_NET_RPMSG=y
Signed-off-by: wushenhui <wushenhui@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua 74b75590cb GDBus:Set DBUS_TIMEOUT_INFINITE timer that is no dbus timeout
No need add reply timer for async method call.
if set -1, that is dbus default timer(25s).

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua b1bb85ad39 revert debug assert for method call no reply.
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua 22572fa2f1 GDBus:No need add reply timer for async method call
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua fc535ac9a7 Fix:Get New Added proxy proper need add getting_all_prop flag
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
huangcaihua 7a94a96240 Fix:gdbus notify proxy_added after proxy all properties got.
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:19 +08:00
zhangyu117 dad95e2787 frameworks/system: Fix some minor issues when features on specific product-dev are switched to dev-system
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
2025-12-15 18:24:19 +08:00
zhangbo56 8c2b7f8a4e kvdb: Add more apis for kvdb handle error case
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:19 +08:00
yukangzhi fd01781f55 frameworks/system/utils: Resolve compilation warnings
clang-format the file include/cutils/trace.h

"/home/mi/workspace_vela/nuttx/../apps/frameworks/
system/utils/include/cutils/trace.h", line 154: warning #1731-D:
          function must be declared at file scope
          void atrace_begin_body(const char*);
               ^
"/home/mi/workspace_vela/nuttx/../apps/frameworks/
system/utils/include/cutils/trace.h", line 167: warning #1731-D:
          function must be declared at file scope
          void atrace_end_body(void);
               ^
"/home/mi/workspace_vela/nuttx/../apps/frameworks/
system/utils/include/cutils/trace.h", line 185: warning #1731-D:
          function must be declared at file scope
          void atrace_async_begin_body(const char*, int32_t);
               ^
"/home/mi/workspace_vela/nuttx/../apps/frameworks/
system/utils/include/cutils/trace.h", line 198: warning #1731-D:
          function must be declared at file scope
          void atrace_async_end_body(const char*, int32_t);
               ^

Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
2025-12-15 18:24:19 +08:00
daichuan ed778af5a9 add for the vendor partition code can use kvdb
Signed-off-by: daichuan <daichuan@xiaomi.com>
2025-12-15 18:24:19 +08:00
zhangbo56 4ec33c844e trace: Default enable trace.c compile
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:19 +08:00
zhaoxingyu1 4c070d84b0 framework/kvdb: modify kvdb depends on !MTD_CONFIG_NONE
Signed-off-by: zhaoxingyu1 <zhaoxingyu1@xiaomi.com>
2025-12-15 18:24:19 +08:00
hongfengchen dc15b3f58b change murmurhash to static inline
Change murmurhash to static inline.

Signed-off-by: hongfengchen <hongfengchen@xiaomi.com>
2025-12-15 18:24:18 +08:00
hongfengchen 3a898cb303 utils:add unistd.h
Add unistd.h for files in kvdb and log.

Signed-off-by: hongfengchen <hongfengchen@xiaomi.com>
2025-12-15 18:24:18 +08:00
hongfengchen 78f2846dd1 add murmurhash function
Add murmurhash function to map a string to hash int.

Signed-off-by: hongfengchen <hongfengchen@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua 659b244934 Fix:Coverity for spurious wakeup and null check_after_deref
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua 1da41823bb Fix:GDbus get prop sync from default loop
GDbus cache the proxy properties, for multi-thread, one thread gets
prop value which maybe freed by default loop thread.

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
xujianhang f96515434f gdbus: Resolve the Bluetooth module's failure to acquire the oFono NetworkOperator service
Signed-off-by: xujianhang <xujianhang@xiaomi.com>
2025-12-15 18:24:18 +08:00
guohao15 daf0204ba9 kvdb:dump more information when API failed
Signed-off-by: guohao15 <guohao15@xiaomi.com>
2025-12-15 18:24:18 +08:00
ligd 749a14fb69 kvdb/server: check space before monitor notify to avoid deadlock
Deadlock:
kvdbd                      client
                           poll monitor
monitor notify
                           recv notify
monitor notify
monitor notify
...
monitor notify
monitor notify
                           property_get() //wait kvdb reponse
monitor notify
//send buf full

Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua d0dbef6f1d Fix: remove signal filter when receive dbus disconnect msg
If the dbus disconnect message has been received,
it means that the current dbus connection is invalid.
The added disconnect message signal filter also needs to be free.

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua 3362b52de2 Fix: Not get all proxy properties when any interface added
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
wenlingyun1 586a2cda63 kvdb/cmake: add command qemuprop
Signed-off-by: wenlingyun1 <wenlingyun1@xiaomi.com>
2025-12-15 18:24:18 +08:00
zhangshoukui f28493904c KVDB_NVS: modify depends on
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:18 +08:00
zhangshoukui 032f1f858f rename property_reload to property_load and Support for passing parameters
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua b22c42a889 Fix:Add user_data for gdbus callback filter.
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
huangcaihua 01dde63642 Fix: Must free client queue handle in async queue close callback func
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:18 +08:00
cuiziwei 1d221149c8 ALOG: Fixed the issue that disable ALOG will print ANDROID_LOG_VERBOSE level logs by default.
Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:18 +08:00
cuiziwei a2858e3dfc apps/frameworks: Add ALOG to select LIBC_PRINT_EXTENSION to print log.
cause ALOG will print log with syslog(g_logprimap[prio], "[%s] %pV\n", tag, &vaf);

Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:18 +08:00
xuxin19 0701595849 cmake(bugfix):add missing kvdb exitprop cmake build
Signed-off-by: xuxin19 <xuxin19@xiaomi.com>
2025-12-15 18:24:18 +08:00
buxiasen a274cb1651 kvdb: use filekv over tmpfs as no-persist kv backend
Persist NVS KVDB and rammtd temporary is not a good case,
Unqlite over tmpfs is much slower than tmpfs.

Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2025-12-15 18:24:17 +08:00
chenrun1 43e35964c3 kvdb:add API exitprop for exit kvdbd server
Summary:
  Added support for the Server exit capability
  1. Add new api property_exit()
  2. Add new command exitprop

dependson:756874

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2025-12-15 18:24:17 +08:00
wangmingrong1 c9d0c2f82d Open source transformation
Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
2025-12-15 18:24:17 +08:00
zhangshoukui 0974feba8e fix compile warning
kvdb/getprop.c:60:9: error: call to undeclared function 'callback'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]

Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:17 +08:00
huangcaihua cfb155730d Fix:Cancel pendingcall when received interface remove message
Gdbus will get properties when received interface add message,
If not cancel the getting properties pendingcall, it maybe use
freed proxy which will be freed after received interface remove message.

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:17 +08:00
huangcaihua 340bd6613e Fix:use async queue API to close async-queue handler
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:17 +08:00
Shanmin Zhang cfda376446 goldfish: convert from qemu.sf.lcd_density to ro.sf.lcd_density
Signed-off-by: Shanmin Zhang <zhangshanmin@xiaomi.com>
2025-12-15 18:24:17 +08:00
Shanmin Zhang 1b0af71102 goldfish: support heartbeat and bootcomplete message.
Signed-off-by: Shanmin Zhang <zhangshanmin@xiaomi.com>
2025-12-15 18:24:17 +08:00
huangcaihua 870af45893 Fix:Add assert when recieve dbus NoReply Error
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:17 +08:00
chenrun1 4057b8981f filekv: add trunk mode when setprop
Summary:
Add O_TRUNC flags in kvdb_file_set, avoid when the first set value is greater than the second overwrite, actual value is wrong

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2025-12-15 18:24:17 +08:00
zhangshoukui 87e7aeb429 Fixed garbled characters displayed on binary keys
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:17 +08:00
chenrun1 3d293393c5 unqlite.c:Add value_len to avoid causing a memory stampede
Summary:
  In the unqlite api, unqlite_kv_fetch must use parameters
1. kvdb handler
2. key
3. key_len
4. value_len
This problem is because when value_len is not provided, the content is assigned to the 0x0 address, which causes the dataabort caught by Kasan

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2025-12-15 18:24:17 +08:00
guoshichao 52f0b2de34 system/utils: fix the inaccurate descriptions in the document
Signed-off-by: guoshichao <guoshichao@xiaomi.com>
2025-12-15 18:24:17 +08:00
huangcaihua 89180702ef Fix: gdbus async send dbus message reply
dbus_connection_send_with_reply returned pendingcall object, then set pendingcall notify function.
When dbus reply, it will call dbus pendingcall handle process, and call notify fuction.
For both thread, ensure that the dbus pendingcall notify is set to execute first, and then execute the dbus reply call notify pendingcall process

Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:17 +08:00
xuxin19 a64bdce895 utils(build):refactor frameworks system build
Signed-off-by: xuxin19 <xuxin19@xiaomi.com>
2025-12-15 18:24:17 +08:00
yintao 1b3ed4a5ac kvdb: add retry to avoid kvdb not being started
connect will return ENOENT if kvdb server not being started when use local socket
so client need to retry connect until kvdb server is listening.

Signed-off-by: yintao <yintao@xiaomi.com>
2025-12-15 18:24:17 +08:00
Shanmin Zhang 46435e4b40 goldfish: add qemu-props for passing boot properties.
Signed-off-by: Shanmin Zhang <zhangshanmin@xiaomi.com>
2025-12-15 18:24:17 +08:00
huangcaihua e3ce03e6ad Fix: Add gdbus API comment
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:17 +08:00
guoshichao 13481a4cd5 framework/utils: add the intro doc and api doc
Signed-off-by: guoshichao <guoshichao@xiaomi.com>
2025-12-15 18:24:17 +08:00
buxiasen 2b334c10d7 kvdb/file: fix typeo in list
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2025-12-15 18:24:17 +08:00
zhangbo56 d2b17914ed kvdb: Fix a build break in Android
Add types header.

Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:16 +08:00
chenrun1 de90faf2e7 kvdb/file.c:Fix overflow return value
Summary:
  1.Change the type of nbyteswrite to size_t
  2.close(dir) before return

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangshoukui 5628656716 Fix compile error
kvdb/client.c: In function 'property_get_binary':
kvdb/client.c:305:29: error: 'len' may be used uninitialized [-Werror=maybe-uninitialized] kvdb/client.c:277:13: note: 'len' was declared here cc1: all warnings being treated as errors

Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangshoukui 042d7d9f36 kvdb_file_get failed should close dir
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangshoukui ad8d2597e6 kvdb: Support storage binary value
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:16 +08:00
dongjiuzhu1 0e595320ab kvdb/server: wait until filesystem mount success or timeout 20ms
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:16 +08:00
chenrun1 b3f60356d8 kvdb/file: Add new optional kvdb backend filekv
Summary:
  Added filekv backend,We need to configure the persist storage location (folder directory) and tmp storage location (folder directory) if we need
  next:Put the file behavior in common so that other backends can use it

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2025-12-15 18:24:16 +08:00
guohao15 5a6ae3f70a kvdb:add new Kconfig to minimize code size
Signed-off-by: guohao15 <guohao15@xiaomi.com>
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
2025-12-15 18:24:16 +08:00
dongjiuzhu1 d1f6afe13a frameworks/kvdb: fix minor issue about set_int64_oneway
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:16 +08:00
haopengxiang 32f6cc0549 utils/kvdb/Kconfig: simplify KVDB_UNQLITE depends on
FS_LOCK_BUCKET_SIZE has been added required in config UNQLITE

config UNQLITE
	bool "UnQLite Database"
	depends on TLS_TASK_NELEM > 0
	depends on FS_LOCK_BUCKET_SIZE > 0
	default n

Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangbo56 301998ea83 kvdb: Modify android build get/set prop name
1. Set name to kvset/kvget.
2. Move from vendor partition to system partition.

Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangbo56 e842fa444a kvdb: Fix a get int32/int64 with empty key error case
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:16 +08:00
zhangbo56 85de640853 kvdb: export kvdb header path for jni use
Signed-off-by: zhangbo56 <zhangbo56@xiaomi.com>
2025-12-15 18:24:16 +08:00
xujianhang d959b76294 frameworks/utils: adjust the code style of log_radio.h to WebKit
Signed-off-by: xujianhang <xujianhang@xiaomi.com>
2025-12-15 18:24:16 +08:00
haopengxiang 2d72c6a7ce frameworks/utils/Makefile: update utils to libutils.a for opt soruce to partner env
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:16 +08:00
xujianhang ec9aa1794c frameworks/utils: allow printing non-debug logs
Signed-off-by: xujianhang <xujianhang@xiaomi.com>
2025-12-15 18:24:16 +08:00
dongjiuzhu1 39e08271d4 frameworks/kvdb: add error log about open failed
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:16 +08:00
xujianhang 3a8a321d4e frameworks/utils: add a switch for ril log
Signed-off-by: xujianhang <xujianhang@xiaomi.com>
2025-12-15 18:24:16 +08:00
xujianhang bdf531019c frameworks/gdbus: fix the bug where method_call_reply is not executed probailistically
When the dbus message returns too quickly, the dbus message may return
before dbus_pending_call_set_notify is executed, resulting in the
callback function not being executed.

Signed-off-by: xujianhang <xujianhang@xiaomi.com>
2025-12-15 18:24:16 +08:00
huangcaihua ca9e7d624c Fix: Add return false check for coverit
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:16 +08:00
liwenxiang1 98afab50c0 utils/kvdb:kvdb_bind adds CONFIG_NET_RPMSG to configure RPMSG server
Open RPMSG configuration to enable RPMSG server, otherwise it will fail to test

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2025-12-15 18:24:15 +08:00
huangcaihua 60c38e022f Fix: remove if null condition that won't be null
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:15 +08:00
dongjiuzhu1 589b535c75 kvdb/server: wait until filesystem mount success
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:15 +08:00
huangcaihua bbf0241519 Fix: Change code to WebKit style
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:15 +08:00
guohao15 351f0454c8 add propset/propget for Android
Signed-off-by: guohao15 <guohao15@xiaomi.com>
2025-12-15 18:24:15 +08:00
huangcaihua ecb3d6bed5 Fix:gDBus support interface to filter proxy
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:15 +08:00
zhangshoukui a07e973574 kvdb unqlite: supports the creation of ro properties, which cannot be modified
Signed-off-by: zhangshoukui <zhangshoukui@xiaomi.com>
2025-12-15 18:24:15 +08:00
cuiziwei 5a83196f1d sim/m64:Fix build warning.
Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:15 +08:00
likun17 c315121abf log_write.c:Adapt the new header file path of va_format.
Signed-off-by: likun17 <likun17@xiaomi.com>
2025-12-15 18:24:15 +08:00
zhanghongyu 43e1c9b33a frameworks/utils: fix cmake build error
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
2025-12-15 18:24:15 +08:00
xuxin19 cad5f9a52a Makefile:add compile CONFIG conditions for frameworks utils
Signed-off-by: xuxin19 <xuxin19@xiaomi.com>
2025-12-15 18:24:15 +08:00
xuxin19 0d07b93011 cmake:add framework utils cmake build
Signed-off-by: xuxin19 <xuxin19@xiaomi.com>
2025-12-15 18:24:15 +08:00
Shoukui Zhang 256d0a4f1f kvdb: Add kvdb depends and configuration help
Signed-off-by: Shoukui Zhang <zhangshoukui@xiaomi.com>
2025-12-15 18:24:15 +08:00
huangcaihua 38fdc66612 Fix: Filter can handle empty dbus signal message without crashing
Signed-off-by: huangcaihua <huangcaihua@xiaomi.com>
2025-12-15 18:24:15 +08:00
wangjianyu3 837fcbb4b5 kvdb: More log for property_commit()
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2025-12-15 18:24:15 +08:00
wangjianyu3 50dd8937e9 kvdb/setprop: Check return value of property_commit()
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2025-12-15 18:24:15 +08:00
wangjianyu3 780614cd9d kvdb: property_commit() waits for kvdb_commit() to complete by default
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2025-12-15 18:24:15 +08:00
xucheng5 2fc25fcc54 kvdb: support config non-persist key-value
dependson:odm_473531 odm_474320

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:15 +08:00
wangmingrong 5d95e3a9d2 kvdb: adjustment code
kvdb_load moved from command. c to server. c

Signed-off-by: wangmingrong <wangmingrong@xiaomi.com>
2025-12-15 18:24:15 +08:00
wanggang26 c6900c902d kvdb: enable O_CLOEXEC explicit
Signed-off-by: wanggang26 <wanggang26@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 3da2f6b4d5 framework/kvdb : optimizate the code
multi definiation for KVDB_MEM , KVDB_COUNT .etc

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 dec3c49ca4 gdbs/pendingcall: Checks whether the pending call has received
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 c36fb62273 kvdb/direct: property_get return the len which not include '\0'
should be the same with server mode

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
Bowen Wang abbbffa922 kvdb/server: fix the monitor bug
VELAPLATFO-10160:VELAPLATFO-10831

This bug is introduced by:
https://gerrit.pt.mioffice.cn/c/vela/frameworks/utils/+/3080162

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 8837aa44bd framework/kvdb : fixed build error
Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 38c863df46 framwork/kvdb: PROP_MSG use heap instead of stack
reduce stack size of getprop/setprop/kvdbd

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 3a75d71df9 kvdb/nvs : 'persist.' prefix auto convert when store
Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 53bf3e7fd8 kvdb/nvs : fixed kvdb list error
configdata should be valid

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 741932da37 gdbus/mainloop: fix memory leak
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
cuiziwei ca08b62bfc frameworks/utils:fix build warning.
binder/Binder.cpp: In member function ‘android::status_t android::BBinder::setRpcClientDebug(android::base::unique_fd, const android::sp<android::IBinder>&)’:
binder/Binder.cpp:529:15: warning: unused variable ‘socketFdForPrint’ [-Wunused-variable]
  529 |     const int socketFdForPrint = socketFd.get();
      |               ^~~~~~~~~~~~~~~~
binder/BpBinder.cpp: In member function ‘void android::BpBinder::ObjectManager::kill()’:
binder/BpBinder.cpp:103:18: warning: unused variable ‘N’ [-Wunused-variable]
  103 |     const size_t N = mObjects.size();
      |                  ^
CC:  vfs/fs_timerfd.c binder/IMemory.cpp: In member function ‘void android::HeapCache::dump_heaps()’:
binder/IMemory.cpp:508:29: warning: unused variable ‘h’ [-Wunused-variable]
  508 |         BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
      |                             ^
binder/RpcServer.cpp: In static member function ‘static void android::RpcServer::establishConnection(android::sp<android::RpcServer>&&, android::base::unique_fd, sockaddr_storage, socklen_t)’:
binder/RpcServer.cpp:286:9: warning: unused variable ‘clientFdForLog’ [-Wunused-variable]
  286 |     int clientFdForLog = clientFd.get();
      |         ^~~~~~~~~~~~~~
CC:  netdb/lib_dnsbind.c binder/RpcState.cpp: In member function ‘void android::RpcState::dumpLocked()’:
binder/RpcState.cpp:269:21: warning: variable ‘desc’ set but not used [-Wunused-but-set-variable]
  269 |         const char* desc;
      |                     ^~~~

Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:14 +08:00
cuiziwei f0787a21ef frameworks/utils:modify the macro definition of LOG_ALWAYS_FATAL_IF.
when close the LOG_ALWAYS_FATAL_IF, retain the conditional statement judgment in LOG_ALWAYS_FATAL_IF.

Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:14 +08:00
cuiziwei 8f6f01ae23 framworks/utils:add CONFIG_ALOG to control log level.
Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:14 +08:00
cuiziwei 14307399b1 framworks/utils:fix clang-format warning.
log_main.h:67:40: warning: code should be clang-formatted [-Wclang-format-violations]
constexpr int __fake_use_va_args(Ts...) {
                                       ^
log_main.h:67:42: warning: code should be clang-formatted [-Wclang-format-violations]
constexpr int __fake_use_va_args(Ts...) {
                                         ^
log_main.h:85:41: warning: code should be clang-formatted [-Wclang-format-violations]
                                        ^
log_main.h:88:48: warning: code should be clang-formatted [-Wclang-format-violations]
                                               ^
log_main.h:102:45: warning: code should be clang-formatted [-Wclang-format-violations]
                                            ^
log_main.h:123:44: warning: code should be clang-formatted [-Wclang-format-violations]
                                           ^
log_main.h:124:34: warning: code should be clang-formatted [-Wclang-format-violations]
  __android_log_assert(cond, tag,                               \
                                 ^
log_main.h:125:64: warning: code should be clang-formatted [-Wclang-format-violations]
                       _android_second(0, ##VA_ARGS_, NULL) \
                                                               ^
log_main.h:135:39: warning: code should be clang-formatted [-Wclang-format-violations]
                                      ^
log_main.h:136:63: warning: code should be clang-formatted [-Wclang-format-violations]
  ((_predict_false(cond)) ? (FAKE_USE_VA_ARGS(VA_ARGS_),                            \
                                                              ^
log_main.h:137:90: warning: code should be clang-formatted [-Wclang-format-violations]
                              ((void)android_printAssert(#cond, LOG_TAG, ##_VA_ARGS_))) \
                                                                                         ^
log_main.h:142:30: warning: code should be clang-formatted [-Wclang-format-violations]
                             ^
log_main.h:201:19: warning: code should be clang-formatted [-Wclang-format-violations]
                  ^
log_main.h:202:7: warning: code should be clang-formatted [-Wclang-format-violations]
  do {                               \
      ^
log_main.h:203:37: warning: code should be clang-formatted [-Wclang-format-violations]
    _FAKE_USE_VA_ARGS(VA_ARGS_); \
                                    ^
log_main.h:204:17: warning: code should be clang-formatted [-Wclang-format-violations]
    if (false)

{                     \                 ^ log_main.h:205:28: warning: code should be clang-formatted [-Wclang-format-violations]       __ALOGV(__VA_ARGS__);          \                            ^ log_main.h:206:6: warning: code should be clang-formatted [-Wclang-format-violations]     }
                               \
     ^
log_main.h:217:28: warning: code should be clang-formatted [-Wclang-format-violations]
                           ^
log_main.h:218:27: warning: code should be clang-formatted [-Wclang-format-violations]
  ((__predict_false(cond))                                                                \
                          ^
log_main.h:219:90: warning: code should be clang-formatted [-Wclang-format-violations]
       ? (_FAKE_USE_VA_ARGS(VA_ARGS), (void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS_)) \
                                                                                         ^
log_main.h:232:28: warning: code should be clang-formatted [-Wclang-format-violations]
                           ^
log_main.h:233:27: warning: code should be clang-formatted [-Wclang-format-violations]
  ((__predict_false(cond))                                                              \
                          ^
log_main.h:234:88: warning: code should be clang-formatted [-Wclang-format-violations]
       ? (_FAKE_USE_VA_ARGS(VA_ARGS), (void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS_)) \
                                                                                       ^
log_main.h:246:28: warning: code should be clang-formatted [-Wclang-format-violations]
                           ^
log_main.h:247:27: warning: code should be clang-formatted [-Wclang-format-violations]
  ((__predict_false(cond))                                                             \
                          ^
log_main.h:248:87: warning: code should be clang-formatted [-Wclang-format-violations]
       ? (_FAKE_USE_VA_ARGS(VA_ARGS), (void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS_)) \
                                                                                      ^
log_main.h:260:28: warning: code should be clang-formatted [-Wclang-format-violations]
                           ^
log_main.h:261:27: warning: code should be clang-formatted [-Wclang-format-violations]
  ((__predict_false(cond))                                                             \
                          ^
log_main.h:262:87: warning: code should be clang-formatted [-Wclang-format-violations]
       ? (_FAKE_USE_VA_ARGS(VA_ARGS), (void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS_)) \
                                                                                      ^
log_main.h:274:28: warning: code should be clang-formatted [-Wclang-format-violations]
                           ^
log_main.h:275:27: warning: code should be clang-formatted [-Wclang-format-violations]
  ((__predict_false(cond))                                                              \
                          ^
log_main.h:276:88: warning: code should be clang-formatted [-Wclang-format-violations]
       ? (_FAKE_USE_VA_ARGS(VA_ARGS), (void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS_)) \
                                                                                       ^
log_main.h:368:35: warning: code should be clang-formatted [-Wclang-format-violations]
                                  ^
log_main.h:371:35: warning: code should be clang-formatted [-Wclang-format-violations]
                                  ^

Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
2025-12-15 18:24:14 +08:00
xucheng5 eb1bcb28b7 KVDB : support NVS
KVDB use unqlite by default. NVS will be another choice

dependson: 965665 965758 partner_22343 partner_22348 partner_22347 partner_22345 partner_22354 partner_22397

Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 1f2d4109c8 gdbus/client: fix client->ready() multiple calling issue
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 5d7b8476fd gdbus/client: add dbus_proxy_remove_property_watch to free userdata
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 1c48274b13 gdbus/client: support to control get properties for every proxy
neededby:964476

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
yuanchengcheng 3906389b88 kvdb : kvdb supports the mode without server
In the case of a single core, there is no need to monitor the rpmsg socket, and the client can directly call the interface set and get attributes

Signed-off-by: yuanchengcheng <yuanchengcheng@xiaomi.com>
2025-12-15 18:24:14 +08:00
Xiang Xiao 6cce5b24f1 kvdb: Rename CONFIG_KVDB_LOG_LEVEL_xxx to CONFIG_KVDB_LOG_xxx
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:14 +08:00
dongjiuzhu1 f755596ba2 gdbus/client: fix bug about using stack var save ptr of realloc issue
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:14 +08:00
cuiziwei 42769586a9 Revert "trace: Add atrace_is_ready like android"
This reverts commit 95f13f779aab601f9bc6c857d35bea55b38d146e.

Reason for revert: <CC:  spawn/lib_psa_getstackaddr.c trace/trace.c:25:6: error: conflicting type qualifiers for ‘atrace_is_ready’
   25 | bool atrace_is_ready = true;
      |      ^~~~~~~~~~~~~~~>
2025-12-15 18:24:13 +08:00
Xiang Xiao e84ea52cd1 kvdb: Move the internal macro to internal.h
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:13 +08:00
Xiang Xiao 1f4cc057d1 trace: Add atrace_is_ready like android
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai 011277f8dd replace "shell $(INCDIR)" to "${INCDIR_PREFIX}
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
Xiang Xiao 63234d6d24 kvdb: Implement __system_property_read and __system_property_get
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:13 +08:00
Xiang Xiao 9a03af414d kvdb: Don't include sys/cdefs.h in system_properties.h since is specific to bionic/newlib
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:13 +08:00
dongjiuzhu1 4ae79fdc0e gdbus/client: call proxy_added() when proxy property parse done.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai 538d155110 cutils/trace: update trace.h
Be consistent with external/android/libcutils/libcutils/include/cutils/trace.h

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai a0d217d9d5 cutils/trace: add atrace command
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai df25b39a1e utils: Add atrace support
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yuanchengcheng 922929e6ca kvdb : modify the kvdb unqlite backend
Remove database-related operations from the server

Signed-off-by: yuanchengcheng <yuanchengcheng@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai 123016bb6c cutils/properties: remove __has_include in properties.h
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai a711f560cf cutils/trace: remove stdatomic.h in trace.h
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai 7c533cd68c cutils/trace: remove CC_UNLIKELY in trace.h
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
yinshengkai f57701ee79 utils/trace: fix compile warnings
warning: function declaration isn't a prototype [-Wstrict-prototypes]
  141 | void atrace_init();

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
2025-12-15 18:24:13 +08:00
wangbowen6 c52a822b49 kvdb: move error log config to correct place and remove unused kconfig
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:13 +08:00
yintao d5ee442b35 utils/Makefile: adjust for internal and partner build
relese gdbus for partner

Signed-off-by: yintao <yintao@xiaomi.com>
2025-12-15 18:24:13 +08:00
dongjiuzhu1 2b55cb408b framework/gdbus: using libuv replace glib loop
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Signed-off-by: fangzhenwei <fangzhenwei@xiaomi.com>
2025-12-15 18:24:13 +08:00
dongjiuzhu1 5c8862b1e0 gdbus/client: hold pendingcall when get properites to avoid used after free.
when proxy is removed, proxy_free will cancel this pendcall of proxy to avoid
calling pending_reply_cb after proxy was removed, otherwise it will caused used
after free.

==174637==ERROR: AddressSanitizer: heap-use-after-free on address 0xf507c524 at pc 0x5ada152d bp 0xef013f98 sp 0xef013f88
READ of size 4 at 0xf507c524 thread T0
    #0 0x5ada152c in get_properties_reply_not_standard gdbus/client.c:1271
    #1 0x5ada00b3 in method_call_reply gdbus/client.c:1110
    #2 0x5a527468 in _dbus_pending_call_finish_completion dbus/dbus/dbus-pending-call.c:243
    #3 0x5a4e753d in complete_pending_call_and_unlock dbus/dbus/dbus-connection.c:2332
    #4 0x5a4f39d4 in dbus_connection_dispatch dbus/dbus/dbus-connection.c:4663
    #5 0x5a6d5451 in message_dispatch gdbus/mainloop.c:55
    #6 0x5a644109 in g_idle_dispatch glib/glib/gmain.c:6157
    #7 0x5a6364a3 in g_main_dispatch glib/glib/gmain.c:3477
    #8 0x5a63dbdd in g_main_context_dispatch glib/glib/gmain.c:4195
    #9 0x5a63e6db in g_main_context_iterate glib/glib/gmain.c:4271
    #10 0x5a63f998 in g_main_loop_run glib/glib/gmain.c:4471
    #11 0x5ad2ddda in telephonytool_main /home/mage1/data/specific product_sim_new/frameworks/telephony/telephony_tool.c:4465
    #12 0x58f60272 in nxtask_startup sched/task_startup.c:70
    #13 0x58ef82b8 in nxtask_start task/task_start.c:134

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:12 +08:00
wangbowen6 d59e246ac9 kvdb: add error log in kvdb
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:12 +08:00
yintao 7bb83eb141 utils/gdbus:Fix compile conflict
frameworks/utils/gdbus/polkit.c:139: multiple definition of polkit_check_authorization; /external/ofono/ofono/gdbus/polkit.c:157: first defined here

Signed-off-by: yintao <yintao@xiaomi.com>
2025-12-15 18:24:12 +08:00
yintao cd00843d95 gdbus/watch.c: fix filter_data_call_and_free double free
ERROR: AddressSanitizer: attempting to call malloc_usable_size() for pointer which is not owned
#5 0x59c7dfb4 in filter_data_free gdbus/watch.c:221
    #6 0x59c7f10c in filter_data_call_and_free gdbus/watch.c:324
    #7 0x5aba939a in dbus_remove_all_watches gdbus/watch.c:824
    #8 0x5ab6b274 in tapi_close /home/yintao/ofo/220tele/frameworks/telephony/tapi_manager.c:369
    #9 0x5ab5238e in telephonytool_main /home/yintao/ofo/220tele/frameworks/telephony/telephony_tool.c:3422

Signed-off-by: yintao <yintao@xiaomi.com>
2025-12-15 18:24:12 +08:00
wangbowen6 84cbd352a7 kvdb/server: epoll delete the monitor fd when send error
otherwise, the epoll_wait will failed and busy loop the kvdbd

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:12 +08:00
wangbowen6 6cf17ba1cc kvdb: format client.c and server.c to clang-format
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:12 +08:00
qinwei1 6af0b987fa frameworks: utils: add miss function for binder porting
Summary:
   add __android_log_error_write function for binder porting

Signed-off-by: qinwei1 <qinwei1@xiaomi.com>
2025-12-15 18:24:12 +08:00
haopengxiang 3854b4a7f4 utils/Makefile: adjust for internal and partner build
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:12 +08:00
fangzhenwei 6857500e2f gdbus: move gdbus.h to utils/gdbus folder
neededby:904087

Signed-off-by: fangzhenwei <fangzhenwei@xiaomi.com>
2025-12-15 18:24:12 +08:00
wangbowen6 2b5bcd4b18 log/log_write: add android log system wrapper layer
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:12 +08:00
Xiang Xiao 6f4746bc49 kvdb: Fix typo error
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:12 +08:00
Xiang Xiao 9c24729a48 Move kvdb from kvdb/ to utils/kvdb/
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:12 +08:00
openvela-robot acdd224a19 Merge branch 'dev' of kvdb into dev 2025-12-15 18:24:12 +08:00
openvela-robot 77a691d476 init kvdb
Signed-off-by: zhangning21 <zhangning21@xiaomi.com>
2025-12-15 18:24:12 +08:00
openvela-robot 99415b2b1c Remove __INTRODUCED_IN from android/set_abort_message.h
since it is Android specific version not suitable for vela at all

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:12 +08:00
Xiang Xiao 56592a57bf Move NuttX special funcion to kvdb.h
and sync properties.h with Android 13

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:11 +08:00
openvela-robot 8c65ef7f65 Move PROP_NAME_MAX and PROP_VALUE_MAX to system_properties.h
and sync system_properties.h with android 13

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:11 +08:00
openvela-robot b572ba5216 frameworks/gdbus: fix kasan report error because stack var overflow
When the type of basic value is double, can't using void *value as buffer to get value.

==3263760==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xefe13c30 at pc 0x577c0356 bp 0xefe139b8 sp 0xefe139a8
WRITE of size 8 at 0xefe13c30 thread T0
    #0 0x577c0355 in _dbus_marshal_read_basic dbus/dbus/dbus-marshal-basic.c:581
    #1 0x5783bedb in _dbus_type_reader_read_basic dbus/dbus/dbus-marshal-recursive.c:879
    #2 0x5776ef72 in dbus_message_iter_get_basic dbus/dbus/dbus-message.c:2376
    #3 0x57e06daa in iter_append_iter gdbus/client.c:222
    #4 0x57e070b1 in prop_entry_update gdbus/client.c:265
    #5 0x57e07454 in prop_entry_new gdbus/client.c:286
    #6 0x57e0793a in add_property gdbus/client.c:322
    #7 0x57e09abd in properties_changed_non_standard gdbus/client.c:544
    #8 0x57df2e00 in signal_filter gdbus/watch.c:394
    #9 0x57df4d57 in message_filter gdbus/watch.c:544
    #10 0x57752dc6 in dbus_connection_dispatch dbus/dbus/dbus-connection.c:4703
    #11 0x57dde7d5 in message_dispatch gdbus/mainloop.c:59
    #12 0x5790e3b8 in g_idle_dispatch glib/glib/gmain.c:6157
    #13 0x57900a31 in g_main_dispatch glib/glib/gmain.c:3477
    #14 0x579080d3 in g_main_context_dispatch glib/glib/gmain.c:4195
    #15 0x57908bcc in g_main_context_iterate glib/glib/gmain.c:4271
    #16 0x57909e7f in g_main_loop_run glib/glib/gmain.c:4471
    #17 0x57dde5b7 in telephonytool_main /home/djz/workspace/test/sim/frameworks/telephony/telephony_tool.c:878
    #18 0x56ea66b5 in nxtask_startup sched/task_startup.c:70
    #19 0x56e541a8 in nxtask_start task/task_start.c:134

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
wangbowen6 b854979073 system_properties: not use atomic operation to solve compile error
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:11 +08:00
openvela-robot 9a524577b0 system_properties: add android system property wrapper layer
There are still three fail test cases (android property test):
1. empty key test, reason: kvdb do not support empty key;
2. long key test, reason: (a) read only property value length can be
   arbitrarily-long in android, kvdb do not support; (b) read only
   property can be set if the property do not exist before, kvdb
   not allowed this action;
3. cached property test, reason: (a) android cached property uses
   serial to judge the [key, value] changed, kvdb can't handle this
   very well; (b) android cached property return the value pointer
   from the shared memory directly for read only property, kvdb
   can't handle this well too.

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 156f8c72bf frameworks/gdbus: replace glib api
1. using dbus-list api to replace glib list.
2. using dbus-hash api to replace glib hash api.
3. using dbus-string api to replace glib string api.
4. using posix memory api to replace glib memory api.
5. ...

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 380ee90b2d framework/gdbus: parse property base non-standard property method.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 82a9c0b5f2 gdbus: remove glib header file from gdbus.h
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 8fbd2ec0c9 framework/gdbus: remove prefix g_ for gdbus api.
1. Remove prefix g_ for all gdbus api
2. Using macro to compatible g_ gdus api

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 67b57fbff7 utils/gdbus: fix compile warning
gdbus/client.c: In function ‘dbus_client_set_proxy_handlers’:
gdbus/client.c:1514:60: warning: declaration of ‘proxy_added’ shadows a global declaration [-Wshadow]
 1514 |                                         GDBusProxyFunction proxy_added,
      |                                         ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
gdbus/client.c:365:13: note: shadowed declaration is here
  365 | static void proxy_added(GDBusClient *client, GDBusProxy *proxy)
gdbus/object.c: In function ‘dbus_pending_error’:

gdbus/object.c:319:51: warning: declaration of ‘pending’ shadows a global declaration [-Wshadow]
  319 |                                 GDBusPendingReply pending,
      |                                 ~~~~~~~~~~~~~~~~~~^~~~~~~
gdbus/object.c:76:16: note: shadowed declaration is here
   76 | static GSList *pending = NULL;
      |                ^~~~~~~

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
dongjiuzhu1 1fc1c07c3d Revert "gdbus: fix compile break[workaround]"
This reverts commit d1ba28fc5cbc0e4518eced037ec3bf49768b33b0.
2025-12-15 18:24:11 +08:00
dongjiuzhu1 373a7a856f gdbus: fix compile break[workaround]
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:11 +08:00
Luiz Augusto von Dentz 969f21eca4 gdbus: Emit InterfacesAdded of parents objects first
This makes InterfacesAdded respect the object hierarchy in case its
parent has pending interfaces to be added.

Fixes: https://github.com/bluez/bluez/issues/272
Fixes: https://github.com/bluez/bluez/issues/284
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1534857
Fixes: https://bugs.archlinux.org/task/57464
2025-12-15 18:24:10 +08:00
Tedd Ho-Jeong An 47341f1878 gdbus: Add SPDX License Identifier
This patch adds SPDX License Identifier and removes the license text.

-------------------------------------
       License            COUNT
-------------------------------------
 GPL-2.0-or-later     :      6

License: GPL-2.0-or-later
   gdbus/mainloop.c
   gdbus/object.c
   gdbus/polkit.c
   gdbus/client.c
   gdbus/watch.c
   gdbus/gdbus.h
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz 3571298c49 gdbus: Make g_dbus_proxy_get_path take const proxy
This makes g_dbus_proxy_get_path take const proxy since it doesn't
change anything on the proxy and avoid pointless casts.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz f547545e8c gdbus: Split validation of object path and interface
This splits the validation of object and interface so and error is
properly printed for each of those.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz b121603315 gdbus: Make sure the object path and interface are valid
D-Bus object path and interface must be validate otherwise it can cause
errors as follow:

0  0xb7f67ab1 in __kernel_vsyscall ()
1  0xb7ca1cc1 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
2  0xb7ca50ee in abort () at abort.c:92
3  0xb7e30ba5 in _dbus_abort () at dbus-sysdeps.c:94
4  0xb7e267a6 in _dbus_warn_check_failed (
    format=0xb7e36cd4 "arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\nThis is normally a bug in some application using the D-Bus library.\n") at dbus-internals.c:290
5  0xb7e16d9f in dbus_message_iter_append_basic (iter=0xbf864400, type=111,
    value=0xd70940) at dbus-message.c:2586
6  0x004fcdec in emit_interfaces_added (user_data=0xd70938)
    at gdbus/object.c:574
2025-12-15 18:24:10 +08:00
Marcel Holtmann a991b6e0d9 build: Move declaration of _GNU_SOURCE back into individual source files 2025-12-15 18:24:10 +08:00
ERAMOTO Masaya a9b1f90a29 gdbus: Introduce functions appending to dbus message 2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz c82af41ced gdbus: Fail to send NULL messages
This should make it safe to call g_dbus_send_message with a NULL
message which is more likely to happen now that g_dbus_create_reply
returns NULL when the message is marked with NO_REPLY flag.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz b0f7382e65 gdbus: Fix replying to messages marked with NOREPLY flag
When a sender flags a D-Bus message as not expecting a reply, it is
against D-Bus policy to send a reply — sending one can result in an
error as reported in:

https://bugzilla.kernel.org/show_bug.cgi?id=198453
2025-12-15 18:24:10 +08:00
ERAMOTO Masaya 15551b602c client: Use g_dbus_proxy_path_lookup() 2025-12-15 18:24:10 +08:00
ERAMOTO Masaya 45ab428a01 gdbus: Introduce g_dbus_proxy_path_lookup()
g_dbus_proxy_path_lookup() returns the path of the proxy that matches the
passed path. It also returns the index of the proxy coming next to the
matched proxy in the passed list.
2025-12-15 18:24:10 +08:00
ERAMOTO Masaya 2b7bb6639b gdbus: Make proxy_lookup() global
Also adds the following feature to g_dbus_proxy_lookup().
 - It is more robust even if a proxy is NULL.
 - It checks if the passed interface is NULL.
 - It looks up from the position of the list specified by the index.
2025-12-15 18:24:10 +08:00
Szymon Janc 6b990db97c gdbus: Fix crash on proxy remove
If proxy was freed due to interface being removed remaining references
are left with NULL client pointer. We need to cancel pending calls that
require client when getting reply.

This fix following crash:
bluetoothd[2773]: src/gatt-database.c:proxy_removed_cb() Proxy removed - removing service: /test/app/hci0/service2
bluetoothd[2773]: src/gatt-database.c:gatt_db_service_removed() Local GATT service removed
bluetoothd[2773]: src/adapter.c:adapter_service_remove() /org/bluez/hci0
bluetoothd[2773]: src/adapter.c:remove_uuid() sending remove uuid command for index 0
bluetoothd[2773]: src/sdpd-service.c:remove_record_from_server() Removing record with handle 0x10008
bluetoothd[2773]: src/gatt-database.c:client_disconnect_cb() Client disconnected
==2773== Invalid read of size 8
==2773==    at 0x485220: proxy_added (client.c:288)
==2773==    by 0x485220: get_all_properties_reply (client.c:316)
==2773==    by 0x515A041: ??? (in /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6)
==2773==    by 0x515DA60: dbus_connection_dispatch (in /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6)
==2773==    by 0x47F2BF: message_dispatch (mainloop.c:72)
==2773==    by 0x4E84049: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==2773==    by 0x4E843EF: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==2773==    by 0x4E84711: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==2773==    by 0x40B51F: main (main.c:770)
==2773==  Address 0x88 is not stack'd, malloc'd or (recently) free'd
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz ecff015e0b gdbus: Force service to start if proxy is created while not connected
Because GetAll is no longer send right away the service may never be
started.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz bbbf8a6575 gdbus: Fix not emiting PropertiesChanged
If and interface is removed while properties are pending it would cause
process_properties_from_interface to clear data->pending_prop when it
should only clear the iface->pending_prop.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz 1f6be796da gdbus: Fix not always appending proxy to the list
Changes introduced by c4df79642f413fd7cd7f7da39c3a1f2a184eccae have a
regression were a proxy may not be appended to the proxy_list causing
tests to fail as the proxies maybe be added multiple time since
proxy_look would not be able to find existing instances.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz f88a3186fb gdbus: Fix calling GetAll while GetManagedObjects is pending
If proxies are created while the client is not ready put them into a
pending list so only if they are not found in GetManagedObject reply
call GetAll.
2025-12-15 18:24:10 +08:00
Vinicius Costa Gomes 930a034820 gdbus: Fix the ordering of signals
Consider the following example:

/foo
  properties: "A", "B"

/bar
  properties: "C", "D"

If during a given mainloop iteration, property "A" of object '/foo' is
changed, then properties "C" and "D" of '/bar', lastly "B" of '/foo',
the current code will emit the PropertiesChanged signals in following
order: "A", "B", "C", "D".

This may confuse applications that have a dependency on the order of
those signals.

This fixes the ordering, so in the example, the order becomes:
"C", "D", "A", B". This is considered not to be a problem, as
applications may use the flag G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH, so
property changed signals are emitted as soon as possible.

The solution is for each object, to reschedule the signals every time a
signal is emitted.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz 360e1f3422 gdbus/client: Use g_dbus_send_message if callback is not set
If the user don't set a function it means it doesn't specific producte about the reply
so g_dbus_send_message can be used.
2025-12-15 18:24:10 +08:00
Luiz Augusto von Dentz 795f529669 gdbus/client: Always call ready callback
Call ready callback regardless of the reply to GetManagedObjects
since otherwise the user code will be left waiting forever when in fact
no proxy will be created.
2025-12-15 18:24:10 +08:00
Grant Erickson 1d2f134d77 gdbus: Move typedefs for interwork with strict compilers
Move enumeration type defintions AFTER the enumerations themselves are
declared and defined such that the header works with strict compilers.

This occurs when building a plugin, compiled with C++, and occurs on
all of:

arm-none-linux-gnueabi-g++ (Sourcery G++ Lite 2010q1-202) 4.4.1
arm-poky-linux-gnueabi-g++ (GCC) 4.8.2
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
2025-12-15 18:24:10 +08:00
Saurav Babu 21e521aab5 gdbus: Fix Memory Leak
Members of data are allocated memory but not freed only data is freed
2025-12-15 18:24:10 +08:00
Philip Withnall 5123353f75 gdbus: Drop message replies if the sender requested no reply
If the sender flags a D-Bus message as not expecting a reply, it is
against system bus policy to send a reply — sending one will result in
errors being sent to us by dbus-daemon.

Magically drop all replies to messages which request no reply.

ofonod is one process which sends BlueZ messages which request no
reply,
when it is setting up a hands-free agent.

This is not a complete fix. In an ideal world, the existing check for
G_DBUS_METHOD_FLAG_NOREPLY would be dropped, as the server should be
prepared to return a reply to every method, if the client requests and
expects one — otherwise the client will time out. However, that’s a
much
bigger change with a much bigger risk of breaking things, so I’ll stick
with this for now.
2025-12-15 18:24:10 +08:00
Johan Hedberg f1f079a03a gdbus: Remove unnecessary empty line 2025-12-15 18:24:10 +08:00
Jakub Pawlowski f57229a71c gdbus: add method for immediate property update
g_dbus_emit_property_changed doesn't send dbus signal immediately. Instead
it stores changed properties, and schedule signal to be send at
g_iddle_add. Additionally, if this method is called few times for some
property, only last value will be sent in property changed signal.

If remote device sends lots of notifications, they're all scheduled to be
notified using this method. This might result in some notifications being
lost.

This patch adds new method, that can immediately send property changed
signal, instead of sheduling it for nearest iddle moment.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 81e370dca4 gdbus: Close private connection if setup fails
Private connection should be properly closed with dbus_connection_close
otherwise libdbus exits with the following error:

  'The last reference on a connection was dropped without closing the
   connection. This is a bug in an application. See
   dbus_connection_unref() documentation for details. Most likely, the
   application was supposed to call dbus_connection_close(), since this
   is a private connection.'
2025-12-15 18:24:09 +08:00
Szymon Janc 5415101d00 gdbus: Fix crash in g_dbus_create_error_valist
Passing NULL format parameter to vsnprintf results in invalid argument
error on glibc. But with some other libc libraries (musl and uClibc)
this results in dereferencing NULL pointer and crash due to
segmentation fault.
2025-12-15 18:24:09 +08:00
Szymon Janc 1bbde9ca87 gdbus: Use g_dbus_create_error_valist internally
There is no need to duplicate code in g_dbus_send_error_valist.
2025-12-15 18:24:09 +08:00
Michael Janssen 7b42da75e7 gdbus: Add g_dbus_get_flags function
The g_dbus_get_flags function enables detection of when the
G_DBUS_FLAG_ENABLE_EXPERIMENTAL is set.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 6e577247af gdbus: Make GDBusClient work without ObjectManager
This makes GDBusClient work normally without ObjectManager.
2025-12-15 18:24:09 +08:00
Arman Uguray eddfa1fc63 gdbus/client: Allow specifying ObjectManager path
GDBusClient currently hard-codes "/" as the remote ObjectManager path.
This is generally incorrect, as an application can choose to expose an
ObjectManager at any well-known path. This patch fixes this by allowing
the user to pass in the ObjectManager path by introducing a new
conctructor "g_dbus_client_new_full".
2025-12-15 18:24:09 +08:00
Arman Uguray bfcccef026 gdbus/client: Don't GetManagedObjects w/o handlers
The client code currently issues GetManagedObjects if new handlers are
set via g_dbus_client_set_proxy_handlers. An application may set these
to NULL before unref'ing a client or to simply prevent further events.
Hence, there is no need to refresh objects or properties if all handlers
are NULL.
2025-12-15 18:24:09 +08:00
Szymon Janc 5ae81a0eb9 gdbus: Fix not calling disconnect function
If daemon gets disconnected from D-Bus sender is NULL. Watches that
was explicitly added with NULL sender (ie disconnected_signal in
g_dbus_set_disconnect_function) should be called anyway.
2025-12-15 18:24:09 +08:00
Arman Uguray 08b1e87b31 gdbus: Don't refresh objects/props if disconnected
If g_dbus_client_set_proxy_handlers gets called from within a
proxy_removed callback, the code may end up refreshing the proxy's
properties and incorrectly access the client's proxy_list as it gets
freed. This patch fixes this, so that get_managed_objects does nothing
if it gets called during a service disconnect.
2025-12-15 18:24:09 +08:00
Alban Crequy 723467c703 gdbus: Fix match rule for NameOwnerChanged
When subscribing to the D-Bus signal NameOwnerChanged from the bus driver,
specify the object path and the sender in the match rule. Otherwise, random
connections on the bus could impersonate the bus driver.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 9cd358432a gdbus: Fix crash when watch is toggled or disconnected
This partially reverts 609873e315e705cff3a62ee904675da06d30f7a4 since it
still necessary to take a reference before calling dbus_watch_handle
since internally it can call watch_info_free as in the following trace:

 Invalid read of size 8
   at 0x121085: watch_func (mainloop.c:105)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
 Address 0x5bbcd90 is 16 bytes inside a block of size 24 free'd
   at 0x4A079AE: free (vg_replace_malloc.c:427)
   by 0x4C7837E: g_free (gmem.c:252)
   by 0x4F708BF: dbus_watch_set_data (dbus-watch.c:614)
   by 0x4F70938: _dbus_watch_unref (dbus-watch.c:132)
   by 0x4F6E9A7: _dbus_transport_handle_watch (dbus-transport.c:884)
   by 0x4F59AFB: _dbus_connection_handle_watch (dbus-connection.c:1497)
   by 0x4F70AF9: dbus_watch_handle (dbus-watch.c:683)
   by 0x121084: watch_func (mainloop.c:103)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz cdb3c9572a gdbus: Fix crash when calling g_dbus_add_service_watch
If g_dbus_add_service_watch is called for service which bus name is
already known the following crash can happen:

invalid read of size 1
  at 0x4C2A2F2: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
  by 0x4E97722: g_strdup (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x405B0C: update_name_cache (watch.c:435)
  by 0x405C37: update_service (watch.c:593)
  by 0x4E7A2A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E7A627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E7AA39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4038EA: client_ready (test-gdbus-client.c:1014)
  by 0x4E9E5E0: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E9E7A5: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E9EB1A: g_test_run_suite (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x403614: main (test-gdbus-client.c:1058)
Address 0x5dbe5d0 is 0 bytes inside a block of size 7 free'd
  at 0x4C28577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
  by 0x4E7FF7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x405B04: update_name_cache (watch.c:434)
  by 0x405C37: update_service (watch.c:593)
  by 0x4E7A2A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E7A627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E7AA39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4038EA: client_ready (test-gdbus-client.c:1014)
  by 0x4E9E5E0: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E9E7A5: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x4E9EB1A: g_test_run_suite (in /usr/lib64/libglib-2.0.so.0.3800.2)
  by 0x403614: main (test-gdbus-client.c:1058)
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz edff96484c Revert "gdbus: Don't include just added interfaces in GetManagedObjects"
This actually creates a problem since the code now does flush any pending
message on the queue any signal will be send right away before the
actual reply to GetManagedObjects which will not contain those interfaces.
2025-12-15 18:24:09 +08:00
Andrei Emeltchenko b2c8718e45 gdbus: Fix use after free
Refactor filter_data_remove_callback so that we do not iterate over
freed pointer.
2025-12-15 18:24:09 +08:00
Claudio Takahasi 21a2544c9d gdbus: Avoid reporting GDBusClient disconnect twice
No matter if disconnection was reported previously, g_dbus_client_unref()
was always calling service disconnect callback. This patch fix the
following scenario:
1) service disconnects from the bus
2) disconnect callback gets called
3) client calls g_dbus_client_unref(), disconnect callback is called
   again.
2025-12-15 18:24:09 +08:00
Claudio Takahasi 337f1b31bb gdbus: Add g_dbus_proxy_set_property_array
This patch adds a new gdbus utility function to allow setting a property
of fixed, and non-fixed values array.
2025-12-15 18:24:09 +08:00
Claudio Takahasi 2df131ce0d gdbus: Add g_dbus_client_set_ready_watch()
This patch adds a new gdbus helper to notify the clients that
GetManagedObjects reply was received and the last proxy has been
informed previously by the proxy_added callback.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 686fc26441 gdbus: Replace g_timeout_add with g_idle_add
Passing 0 as timeout to g_timeout_add should equivalent to g_idle_add.
2025-12-15 18:24:09 +08:00
Anderson Lizardo 282235f941 gdbus: Fix incorrect DBusConnection reference counting
Commit 94d4f8c35f2e8f301aab7f55a6b7ea8d8c26305e attempted to fix a crash
related to improper reference counting, but the main issue was that the
reference was taken only during the function call (which is usually
unnecessary for single thread), but still passed a pointer to
DBusConnection to a function that is called by the mainloop. This left a
window where the DBusConnection can be destroyed.

Fixes this crash on unit/test-gdbus-client:

==32642== Invalid read of size 4
==32642==    at 0x690D0A6: dbus_connection_ref (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804CEDB: message_dispatch (mainloop.c:73)
==32642==    by 0x684580E: g_timeout_dispatch (gmain.c:4450)
==32642==    by 0x6844A75: g_main_context_dispatch (gmain.c:3065)
==32642==    by 0x6844E14: g_main_context_iterate.isra.23 (gmain.c:3712)
==32642==    by 0x68452FA: g_main_loop_run (gmain.c:3906)
==32642==    by 0x804C7D3: client_connect_disconnect
(test-gdbus-client.c:188)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
==32642==  Address 0x709c6e4 is 140 bytes inside a block of size 144
free'd
==32642==    at 0x67E806C: free (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32642==    by 0x692D62E: dbus_free (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x690E1C2: ??? (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804AAEC: destroy_context (test-gdbus-client.c:104)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
2025-12-15 18:24:09 +08:00
Anderson Lizardo 739ae6ef26 gdbus: Fix memory leak
data->conn and data->path must be destroyed before freeing "data".
2025-12-15 18:24:09 +08:00
Bastien Nocera 213fed6add gdbus: Fix trying to remove already removed sources
When we return FALSE from idle handlers, the source is removed.
This will be causing warnings in glib 2.40.

See https://bugzilla.gnome.org/show_bug.cgi?id=710724
2025-12-15 18:24:09 +08:00
Szymon Janc 0465d86991 gdbus: Remove not needed check for NULL DBusPendingCall
It is now checked by g_dbus_send_message_with_reply() so there is no
need to double check that in caller.
2025-12-15 18:24:09 +08:00
Szymon Janc 4c125d6ad5 gdbus: Check for NULL DBusPendingCall in g_dbus_send_message_with_reply
"Warning: if the connection is disconnected or you try to send Unix file
descriptors on a connection that does not support them, the
DBusPendingCall will be set to NULL, so be specific producteful with this."

Check this in g_dbus_send_message_with_reply so that callers don't need
to double check for NULL if g_dbus_send_message_with_reply returned
TRUE.

This also fix crash if passing FD over D-Bus is blocked e.g. by SELinux
policy.

bluetoothd[1894]: profiles/audio/avdtp.c:session_cb()
bluetoothd[1894]: profiles/audio/avdtp.c:avdtp_parse_cmd() Received
    SET_CONFIGURATION_CMD
bluetoothd[1894]: profiles/audio/a2dp.c:endpoint_setconf_ind() Source
    0x6c5000: Set_Configuration_Ind
bluetoothd[1894]: profiles/audio/avdtp.c:avdtp_ref() 0x6df360: ref=1
bluetoothd[1894]: profiles/audio/a2dp.c:setup_ref() 0x6d32b0: ref=1
process 1894: arguments to dbus_pending_call_set_notify() were incorrect,
     assertion "pending != NULL" failed in file dbus-pending-call.c line
     636.
This is normally a bug in some application using the D-Bus library.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 9463f0ab3c gdbus/client: Use g_dbus_add_properties_watch to track properties
This make the handling much simpler and avoids duplicates of the same
match rule.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz bc4c2efd74 gdbus/client: Use g_dbus_add_signal_watch to track signals
This make the handling much simpler and avoids duplicates of the same
match rule.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz b8862d34d3 gdbus/client: Use g_dbus_add_service_watch to track services
This make the handling much simpler and avoids duplicates of the same
match rule.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz d48d0a4b3e gdbus/watch: Fix crash when disconnecting from D-Bus
When disconnecting from D-Bus a message could be recieved with no sender:
Invalid read of size 1
   at 0x4A09EE1: strcmp (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x3B03C386B8: g_str_equal (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x4065D6: message_filter (watch.c:529)
   by 0x3B0700F9E5: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.4)
   by 0x4052E7: message_dispatch (mainloop.c:76)
   by 0x3B03C48962: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3B03C47E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3B03C48157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3B03C48559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x4038C5: client_proxy_removed (test-gdbus-client.c:902)
   by 0x3B03C6B566: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
   by 0x3B03C6B6E5: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
 Address 0x0 is not stack'd, malloc'd or (recently) free'd
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz b9540df318 gdbus/watch: Fix aborting when removing D-Bus filter
In case of filter_data having a watch to a service name it may call
dbus_connection_remove_filter twice causing libdbus to abort:

process 24723: Attempt to remove filter function 0x4063e0 user data (nil), but no such filter has been added

To fix this the code will now only attempt to call
dbus_connection_remove_filter once in filter_data_free which is the
counterpart of filter_data_get where dbus_connection_add_filter is called.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 93e6a09726 gdbus/watch: Fix crash when g_dbus_remove_watch is called from connect callback
at 0x40570C: update_service (watch.c:601)
 by 0x40584B: service_reply (watch.c:627)
 by 0x3B0700C511: ??? (in /usr/lib64/libdbus-1.so.3.7.4)
 by 0x3B0700F740: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.4)
 by 0x405167: message_dispatch (mainloop.c:76)
 by 0x3B03C48962: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
 by 0x3B03C47E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
 by 0x3B03C48157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
 by 0x3B03C48559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
Address 0x4c58a30 is 32 bytes inside a block of size 56 free'd
 at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
 by 0x3B03C4D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
 by 0x406102: filter_data_remove_callback (watch.c:378)
 by 0x405FC0: g_dbus_remove_watch (watch.c:798)
 by 0x40A22B: g_dbus_client_unref (client.c:1227)
 by 0x40570B: update_service (watch.c:599)
 by 0x40584B: service_reply (watch.c:627)
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 0c5a311077 gdbus: Fix emitting PropertiesChanged twice
This fixes double emission of PropertiesChanged introduced by flushing
changes, the flushing can happen during the pending processing so the
pending_prop flag needs to be updated in the beginning and the list of
properties can be freed before g_dbus_send_message as it is not required
anymore.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz e54a8ccf7b gdbus: Avoid calling dbus_connection_send*
dbus_connection_send* should not be called directly except by
g_dbus_send_message.
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 5f07e053e8 gdbus: Add g_dbus_send_message_with_reply
g_dbus_send_message_with_reply flushes pending signals before calling
dbus_connection_send_with_reply so it does not alter the message order
2025-12-15 18:24:09 +08:00
Luiz Augusto von Dentz 190b579c01 gdbus: Fix sending ObjectManager/Properties signals out of order
In some cases the order of the messages is altered when a message is
sent without processing the pending signals first, currently this affect
client_check_order unit test:

/gdbus/client_check_order: **
ERROR:unit/test-gdbus-client.c:795:property_check_order: assertion failed: (g_strcmp0(string, "value1") == 0)

As can be observed the value of the property is not yet updated because the
signal it is still pending, once this fix is applied the test pass:

/gdbus/client_check_order: OK

Note that the flushing only works when g_dbus_send_message is used so
places where dbus_connection_send and other variants are called directly
may still change the order.
2025-12-15 18:24:09 +08:00
Henrique Dante de Almeida 05bd22dfb6 gdbus: Remove proxies when client disconnects
Remove proxies and generate proxy_removed callbacks even when there are
no corresponding InterfaceRemoved signals.

This patch fixes having zombie gdbus proxy object when a server
disconnects without sending InterfaceRemoved signals. These objects
may interact with new server instances, for example, making
InterfaceAdded signals of new objects with the same name be filtered
out as duplicated, or staying allocated, but unused, if the new server
doesn't reuse the object paths. Note that as a side-effect, the
lifetime of a gdbus proxy becomes stricter: it lives at most for the
duration of a single connection to a single instance of a server
process.
2025-12-15 18:24:08 +08:00
Anderson Lizardo 307e4132eb gdbus: Fix using NULL DBusPendingCall when disconnected from D-Bus
From D-Bus documentation for dbus_connection_send_with_reply():

"Warning: if the connection is disconnected or you try to send Unix file
descriptors on a connection that does not support them, the
DBusPendingCall will be set to NULL, so be specific producteful with this."

Fix these errors when killing D-Bus daemon with the client still
running:

process 5712: arguments to dbus_pending_call_set_notify() were
incorrect, assertion "pending != NULL" failed in file
../../dbus/dbus-pending-call.c line 596.
This is normally a bug in some application using the D-Bus library.
process 5712: arguments to dbus_pending_call_unref() were incorrect,
assertion "pending != NULL" failed in file
../../dbus/dbus-pending-call.c line 572.
This is normally a bug in some application using the D-Bus library.
2025-12-15 18:24:08 +08:00
Anderson Lizardo f2b00d18b6 gdbus: Fix segfault when D-Bus daemon exits
Fix this crash if D-Bus exits while the client is still connected to it:

==5570== Invalid read of size 1
==5570==    at 0x402D28E: strcmp (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5570==    by 0x4070E22: g_str_equal (ghash.c:1704)
==5570==    by 0x8055F61: message_filter (client.c:1123)
==5570==    by 0x4141500: dbus_connection_dispatch (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==5570==    by 0x80506F7: message_dispatch (mainloop.c:76)
==5570==    by 0x4081A7E: g_timeout_dispatch (gmain.c:3882)
==5570==    by 0x4080D85: g_main_context_dispatch (gmain.c:2539)
==5570==    by 0x4081124: g_main_context_iterate.isra.21 (gmain.c:3146)
==5570==    by 0x408156A: g_main_loop_run (gmain.c:3340)
==5570==    by 0x41BF4D2: (below main) (libc-start.c:226)
==5570==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5570==
==5570==
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz cabe78d7a6 gdbus: Fix calling GetManagedObjects twice in a row
Calling g_dbus_client_new followed by g_dbus_client_set_proxy_handlers
cause two calls to GetManagedObjects in a row as GetNameOwner reply is
asyncronously it triggers the second call because the handlers have
been set by g_dbus_client_set_proxy_handlers.
2025-12-15 18:24:08 +08:00
Lucas De Marchi d57b1979d5 gdbus: Use gcc builtin instead of g_atomic
g_atomic_* end up using G_STATIC_ASSERT, causing gcc 4.8 to yell due to
-Wunused-local-typedefs.

gdbus/client.c: In function ‘g_dbus_client_ref’:
/usr/include/glib-2.0/glib/gmacros.h:162:53: error: typedef ‘_GStaticAssertCompileTimeAssertion_2’ locally defined but not used [-Werror=unused-local-typedefs]
 #define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1]
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz 3564bc897f gdbus: Fix not calling property_changed callback
In case a property did not appear by the time proxy_added was called
property_changed has to be called if it appear latter otherwise the
application will be unaware of it.
2025-12-15 18:24:08 +08:00
Tomasz Bursztyka 640c13a7da gdbus: Always unreference the message in g_dbus_send_message()
A quick fix on g_dbus_send_message(), if check_signal() fails it returns
FALSE without unreferencing the message as it should. This patch fixes
it.
2025-12-15 18:24:08 +08:00
Denis Kenzior ea704f767b gdbus: Add g_dbus_proxy_set_removed_watch 2025-12-15 18:24:08 +08:00
Vinicius Costa Gomes 9f71038908 gdbus: Fix missing PropertiesChanged signal
If D-Bus ObjectManager is not supported, InterfacesAdded signal
checking needs to be ignored otherwise PropertiesChanged signal
will never be sent.
2025-12-15 18:24:08 +08:00
Marcel Holtmann 24a199849e gdbus: Don't call property changed callback during client init
When the client uses ObjectManager to init properties, do not call
property changed callbacks. They should only be called once the proxy
added has been successfully signaled since the proxy itself provides
a full copy of available properties.
2025-12-15 18:24:08 +08:00
Johan Hedberg f0cc3f1a51 gdbus: Fix unpublished interface signal emission
If we haven't published an interface yet (i.e. it's in the data->added
list), we should just ignore any property changed indications as the
values for the properties will anyway be part of the InterfacesAdded
signal.
2025-12-15 18:24:08 +08:00
Marcel Holtmann f6328ee282 gdbus: Check for valid path before handling properties 2025-12-15 18:24:08 +08:00
Anderson Lizardo 5533e47eef gdbus: Fix memory leak on properties_set()
The pointer returned by dbus_message_iter_get_signature() must be freed
with dbus_free().

Fixes this memory leak:

==1857== 16 bytes in 1 blocks are definitely lost in loss record 104 of
251
==1857==    at 0x402BF52: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==1857==    by 0x415E286: dbus_realloc (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==1857==    by 0x415E70B: ??? (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==1857==    by 0x415F17B: ??? (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==1857==    by 0x414CB33: dbus_message_iter_get_signature (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==1857==    by 0x8053239: properties_set (object.c:899)
==1857==    by 0x5FFFFF: ???
==1857==
2025-12-15 18:24:08 +08:00
Marcel Holtmann 1e875eee5c gdbus: Check signature of property value before calling setter 2025-12-15 18:24:08 +08:00
Lucas De Marchi 0d9a354d5e gdbus: Don't include just added interfaces in GetManagedObjects
If we received a call to ObjectManager.GetManagedObject we should not
include in the response the interfaces in data->added. This is because
it's not guaranteed that those interfaces will trigger an
InterfacesAdded signal, which is the case if the interface is removed in
the same mainloop iteration.
2025-12-15 18:24:08 +08:00
Lucas De Marchi 344b724082 gdbus: Simplify generated introspection
The generated introspection is not supposed to be read as is by human,
so there's no point in printing the indentation or writing more code to
use auto-close tags.

If it's desired to read the raw xml file, user can always use other
tools to transform the output such as "xmllint --format".

This also fixes a missing </property> when property is deprecated.
2025-12-15 18:24:08 +08:00
Marcel Holtmann 8585f8dafc gdbus: Hold client reference during get name owner reply 2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz 50a8e5b3e3 gdbus: Call check_signals when sending signals with g_dbus_send_message
If message passed to g_dbus_send_message is a signal verify if it is a
valid and there really exists an interface with respective signal name.
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz b8757ac11d gdbus: Check if the interface being registered is valid
This prevent registering interfaces that are empty or have all members
marked as experiemental.
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz b02c416e7e gdbus: Introduce G_DBUS_PROPERTY_FLAG_EXPERIMENTAL
This flag can be used to mark properties as experimental, marked
properties are disabled by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz f0655f8b0f gdbus: Introduce G_DBUS_SIGNAL_FLAG_EXPERIMENTAL
This flag can be used to mark signals as experimental, marked
signals are disabled by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
2025-12-15 18:24:08 +08:00
Luiz Augusto von Dentz efcaeb68c0 gdbus: Introduce G_DBUS_METHOD_FLAG_EXPERIMENTAL
This flag can be used to mark methods as experimental, marked
methods are disable by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
2025-12-15 18:24:08 +08:00
Marcel Holtmann 251c7c08b5 gdbus: Include changed properties only once per signal 2025-12-15 18:24:08 +08:00
Marcel Holtmann 0697bc24e9 gdbus: Update properties on D-Bus client re-connections 2025-12-15 18:24:08 +08:00
Marcel Holtmann 9a0702bccb gdbus: Add function to manually refresh properties 2025-12-15 18:24:08 +08:00
Marcel Holtmann e9317d35ea gdbus: Add support for proxy property change notifications 2025-12-15 18:24:08 +08:00
Marcel Holtmann 7564954162 gdbus: Fix handling of client connect/disconnect signals 2025-12-15 18:24:08 +08:00
Marcel Holtmann 9303ef8a16 gdbus: Protect standalone proxy creation with client reference 2025-12-15 18:24:08 +08:00
Marcel Holtmann 41f8504c6c gdbus: Use object manager only if callback functions are set 2025-12-15 18:24:08 +08:00
Marcel Holtmann 727c8ef15d gdbus: Use client service name and not hardcoded org.bluez 2025-12-15 18:24:08 +08:00
Marcel Holtmann d79816cdf0 gdbus: Add support for creating D-Bus proxies without object manager 2025-12-15 18:24:08 +08:00
Marcel Holtmann 0cfd7e7442 gdbus: Avoid using g_ptr_array_new_full convenience function
The g_ptr_array_new_full function only got introduced with GLib 2.30
and to avoid requiring a newer GLib use g_ptr_array_set_free_func instead.
2025-12-15 18:24:08 +08:00
Marcel Holtmann b698b288cf gdbus: Increase the method call timeout to 5 minutes 2025-12-15 18:24:08 +08:00
Marcel Holtmann 08bc2fca82 gdbus: Add helper for sending async error replies 2025-12-15 18:24:07 +08:00
Marcel Holtmann e1fc5e77f5 gdbus: Fix race condition with creating duplicate client proxies 2025-12-15 18:24:07 +08:00
Marcel Holtmann f95e6a90e8 gdbus: Fix issue with unref of client while parsing interfaces 2025-12-15 18:24:07 +08:00
Marcel Holtmann 045f081101 gdbus: Fix issue with unref of client in connect handler 2025-12-15 18:24:07 +08:00
Marcel Holtmann 7129b56fbc gdbus: Add support for D-Bus client method calls 2025-12-15 18:24:07 +08:00
Marcel Holtmann abe73a67dc gdbus: Add callback support for handling property changes 2025-12-15 18:24:07 +08:00
Marcel Holtmann d599968b1e gdbus: Handle property changed signals and update property 2025-12-15 18:24:07 +08:00
Marcel Holtmann 014b4b8d15 gdbus: Set property changed filter match rule for each proxy 2025-12-15 18:24:07 +08:00
Marcel Holtmann d61a3d45d1 gdbus: Use a GPtrArray for the match rules 2025-12-15 18:24:07 +08:00
Marcel Holtmann da5bc70d74 gdbus: Add support for setting D-Bus client basic properties 2025-12-15 18:24:07 +08:00
Marcel Holtmann c3226b8206 gdbus: Deep copy of variants also requires a signature 2025-12-15 18:24:07 +08:00
Marcel Holtmann 5a5c810bc9 gdbus: Add support for complex D-Bus client properties 2025-12-15 18:24:07 +08:00
Marcel Holtmann 6409610b7e gdbus: Add support for D-Bus client properties 2025-12-15 18:24:07 +08:00
Marcel Holtmann 1efcc10131 gdbus: Add support for D-Bus client proxies 2025-12-15 18:24:07 +08:00
Marcel Holtmann 4af3a499b6 gdbus: Add helper functions for simple D-Bus clients 2025-12-15 18:24:07 +08:00
Johan Hedberg 37869d91db Revert "Ensure config.h is included by using CPPFLAGS"
This reverts commit 76919ad7f431167cecdd3d608c1465961aa75423.

The patch needs to be split up and the gdbus/ changes were bogus
compared to the original commit message.

Conflicts:
	Makefile.am
	Makefile.obexd
	profiles/cyclingspeed/cyclingspeed.c
	profiles/heartrate/heartrate.c
	src/error.c
2025-12-15 18:24:07 +08:00
Lucas De Marchi 3ec486e4bf Ensure config.h is included by using CPPFLAGS
Instead of trying to include config.h in each file over the tree and
possibly forgetting to include it, give a "-include config.h" argument
to the compiler so it's guaranteed that a) it will be included for all
source files and b) it will be the first header included.

gdbus/ directory is left out, since it would break other projects using
it.
2025-12-15 18:24:07 +08:00
Luiz Augusto von Dentz 1e8bff6d19 gdbus: Add g_dbus_add_properties_watch function
Convenient function to create watches for D-Bus properties.
2025-12-15 18:24:07 +08:00
Lucas De Marchi d7bcab298b gdbus: Don't automatically attach ObjectManager
Let each project attach the object manager interface instead of
registering it automatically.
2025-12-15 18:24:07 +08:00
Lucas De Marchi e8c3ce5bc8 gdbus: Don't register DBus.Properties with no properties
Delay registering DBus.Properties interface until the moment there are
properties on that path. This is needed for objects that currently don't
expose any property to not export the interface.
2025-12-15 18:24:07 +08:00
Szymon Janc 47c7738b3f gdbus: Remove not needed NULL pointer checks
g_strdup returns NULL if argument passed is NULL and there is no need
to double check that.
2025-12-15 18:24:07 +08:00
Syam Sidhardhan e254b4b208 gdbus: Replace leading spaces with tabs
Trivial formatting fix.
2025-12-15 18:24:07 +08:00
Syam Sidhardhan d5b39ecf8c gdbus: Fix compilation error due to missing #defines
Since these are simple #define strings, we are defining it here
instead of upgrading to D-Bus 1.5 or later.

Log:
  CC     gdbus/object.o
gdbus/object.c: In function ‘properties_set’:
gdbus/object.c:876:7: error: ‘DBUS_ERROR_UNKNOWN_PROPERTY’ undeclared
 (first use in this function)
gdbus/object.c:876:7: note: each undeclared identifier is reported
 only once for each function it appears in
gdbus/object.c:881:6: error: ‘DBUS_ERROR_PROPERTY_READ_ONLY’
 undeclared (first use in this function)
make[1]: *** [gdbus/object.o] Error 1
make: *** [all] Error 2
2025-12-15 18:24:07 +08:00
Lucas De Marchi c32337cef6 gdbus: Remove connection from pending_property functions
The reply to a DBus.Properties.Set() method call should go through the
same D-Bus connection. Thus remove the DBusConnection parameter from the
following functions:

    - g_dbus_pending_property_success()
    - g_dbus_pending_property_error_valist()
    - g_dbus_pending_property_error()
2025-12-15 18:24:07 +08:00
Johan Hedberg 6d6169eb12 gdbus: Fix invalid memory access during interface removal
If an interface is removed from the root path during the same mainloop
iteration that it was added we need to check for data->added before
doing the check for data->parent == NULL in the remove_interface()
function. Otherwise the added interface doesn't get removed from the
data->added list and will result in accessing freed memory:

==337== Invalid read of size 8
==337==    at 0x4F65AFA: dbus_message_iter_append_basic (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x1247B5: append_interface (object.c:556)
==337==    by 0x4C8DC5C: g_slist_foreach (gslist.c:840)
==337==    by 0x1261F7: process_changes (object.c:594)
==337==    by 0x126372: generic_unregister (object.c:997)
==337==    by 0x4F69669: ??? (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x4F5CE51: dbus_connection_unregister_object_path (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x125E81: object_path_unref (object.c:1236)
==337==    by 0x126136: g_dbus_unregister_interface (object.c:1361)
==337==    by 0x14CDF0: service_exit (service.c:581)
==337==    by 0x177556: plugin_cleanup (plugin.c:242)
==337==    by 0x12221F: main (main.c:559)
==337==  Address 0x5bc1550 is 0 bytes inside a block of size 56 free'd
==337==    at 0x4A079AE: free (vg_replace_malloc.c:427)
==337==    by 0x4C7850E: g_free (gmem.c:252)
==337==    by 0x125DB0: remove_interface (object.c:671)
==337==    by 0x125E3B: object_path_unref (object.c:1230)
==337==    by 0x126136: g_dbus_unregister_interface (object.c:1361)
==337==    by 0x14CDF0: service_exit (service.c:581)
==337==    by 0x177556: plugin_cleanup (plugin.c:242)
==337==    by 0x12221F: main (main.c:559)
2025-12-15 18:24:07 +08:00
Johan Hedberg f8d73e3b7d gdbus: Add g_dbus_get_properties function
This function can be used to construct custom D-Bus messages containing
the properties for a specific interface on a given path.
2025-12-15 18:24:07 +08:00
Johan Hedberg 73c593eed7 gdbus: Add support for invalidated properties
If there's a pending property but its exists() callback returns false
the property should be considered invalidated and included in the
relevant list of the PropertiesChanged signal.
2025-12-15 18:24:07 +08:00
Johan Hedberg 463be0e5b2 gdbus: Fix processing pending properties in remove_interface() 2025-12-15 18:24:07 +08:00
Lucas De Marchi 36bcc4b2d2 gdbus: Fix up Properties.Set() code path
Minor fixes to make setter actually work:

	- Add propdata in pending_property_set
	- Break loop when we are removing propdata from list and we
	  found it
	- in_args and out_args were swapped
	- interface and method name arguments were swapped
2025-12-15 18:24:07 +08:00
Lucas De Marchi 7ce811eef0 gdbus: Fix invalid memory access while unregistering
If an interface is added and removed on the same mailoop iteration,
ObjectManager would try to send InterfacesAdded signal while running the
idler because the interface was added to data->added list.

This is easily reproduced by forcing an error path in a plugin
registration, like on sap_server_register(), resulting in the following
error:

==11795== Invalid read of size 4
==11795==    at 0x496F592: dbus_message_iter_append_basic (dbus-message.c:2598)
==11795==    by 0x117B39: append_interface (object.c:554)
==11795==    by 0x48955E7: g_slist_foreach (gslist.c:840)
==11795==    by 0x11923B: process_changes (object.c:592)
==11795==    by 0x11956D: generic_unregister (object.c:980)
==11795==    by 0x4973BAC: _dbus_object_tree_unregister_and_unlock (dbus-object-tree.c:516)
==11795==    by 0x4965240: dbus_connection_unregister_object_path (dbus-connection.c:5776)
==11795==    by 0x1178A5: object_path_unref (object.c:1219)
==11795==    by 0x118517: g_dbus_unregister_interface (object.c:1344)
==11795==    by 0x19AF5B: sap_exit (sap.c:385)
==11795==    by 0x13E9E2: sap_server_register (server.c:1428)
==11795==    by 0x13C092: sap_server_probe (manager.c:44)

With this patch we don't send the InterfacesAdded signal, removing it
from data->added while unregistering.
2025-12-15 18:24:07 +08:00
Lucas De Marchi 975a24a1ff gdbus: Implement PropertiesChanged signal 2025-12-15 18:24:07 +08:00
Luiz Augusto von Dentz 960d2d27e9 gdbus: Simplify code for appending properties
This reuse append_properties for GetAll and GetManagedObjects
2025-12-15 18:24:07 +08:00
Luiz Augusto von Dentz 1bac6977af gdbus: Integrates ObjectManager with Properties interface
This appends the properties and its values when using ObjectManager.
2025-12-15 18:24:07 +08:00
Luiz Augusto von Dentz 47c19efa16 gdbus: Only export ObjectManager interface on root path
ObjectManager should be exported only in the root path and list all
the children paths.
2025-12-15 18:24:06 +08:00
Luiz Augusto von Dentz 5725e97799 gdbus: Group interface changes to reduce the amount of signals emitted
InterfacesAdded and InterfacesRemoved can group all the interfaces
changes together in one message.
2025-12-15 18:24:06 +08:00
Luiz Augusto von Dentz 7f639bef49 gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
This implements initial support for ObjectManager, it automatically adds
objects to its parents so no action is needed by daemons to get their
objects managed by this interface.

ObjectManager is part of D-Bus spec since revision 0.17:
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
2025-12-15 18:24:06 +08:00
Lucas De Marchi 94e8a5c67d gdbus: Add properties into Introspectable interface 2025-12-15 18:24:06 +08:00
Lucas De Marchi 5dfbb88b9c gdbus: Implement DBus.Properties.Set method
Contrary to Get() and GetAll(), Set() is asynchronous so we pass an id
to the setter so later it can declare the Set() as successful or
otherwise.
2025-12-15 18:24:06 +08:00
Lucas De Marchi c28afe1653 gdbus: Implement DBus.Properties.GetAll method 2025-12-15 18:24:06 +08:00
Lucas De Marchi 4f094c0501 gdbus: Implement DBus.Properties.Get method 2025-12-15 18:24:06 +08:00
Lucas De Marchi 31d6d4f894 gdbus: Add skeleton of DBus.Properties interface
This interface is responsible for handling properties of all objects in
a given path. Right now it only registers itself, doing nothing useful.
A conversion to this new layout will be done by subsequent patches.

org.freedesktop.org.DBus.Properties spec can be found at
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
2025-12-15 18:24:06 +08:00
Lucas De Marchi 5ac1a6b233 gdbus: Use macros to add annotations
Besides being more readable this way it avoids going over 80 chars.
2025-12-15 18:24:06 +08:00
Lucas De Marchi a7c96b96c2 gdbus: Move typedefs up
Move the typedefs up so they can be used by functions and callbacks.
2025-12-15 18:24:06 +08:00
Luiz Augusto von Dentz 0a70554054 gdbus: Fix not freeing list node by using g_slist_delete_link
g_slist_remove_link does not free the node which can cause leaks so
replace that with g_slist_delete_link which does free memory properly.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 00c7da7fc9 gdbus: Refactor filter_data_find()
Now this function is only used for searching the listeners of a
connection and the other parameters are not needed anymore.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 4ae1ce7ded gdbus: Fix wrong signal handler match
When we add a signal handler with g_dbus_add_signal_watch(), this
function tries to multiplex the matches added in libdbus by checking
if there's a previous filter_data with the same fields. However, if the
field is NULL it accepts as being the same. The result is that the
following watches will use the same filter data:

watch1 = g_dbus_add_signal_watch(conn, BUS_NAME, NULL, iface, member,
						cb1, data1, NULL);
watch2 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path2", iface, member,
						cb2, data2, NULL);
watch3 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path3", iface, member,
						cb3, data3, NULL);

The result is that when a signal arrives with path == "/path2", all 3
callbacks above will be called, with the same signal delivered to all of
them.

Another problem is that, if we invert the calls like below, only signals
to cb1 will never be trigerred, nonetheless it used path == NULL.

watch2 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path2", iface, member,
						cb2, data2, NULL);
watch1 = g_dbus_add_signal_watch(conn, BUS_NAME, NULL, iface, member,
						cb1, data1, NULL);
watch3 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path3", iface, member,
						cb3, data3, NULL);

This is fixed by not multiplexing the matchs with filter data if any of
the fields are different, including being NULL. When a signal arrives,
if a field is NULL we accept it as a match, but not when adding the
signal handler.
2025-12-15 18:24:06 +08:00
Johan Hedberg aea656b090 gdbus: Fix crash when getting disconnected from the bus
When getting disconnected from the bus sometimes (maybe always?)
dbus_watch_handle() can cause the "info" context to be free'd meaning
that we should not try to access it after the call. The only member we
need access to is the connection pointer and as the code already has a
ref() call for it it's only natural to solve the issue by adding a local
variable not dependent on "info".

The backtrace of the crash fixed looks as follows:

 Invalid read of size 8
   at 0x121085: watch_func (mainloop.c:105)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
 Address 0x5bbcd90 is 16 bytes inside a block of size 24 free'd
   at 0x4A079AE: free (vg_replace_malloc.c:427)
   by 0x4C7837E: g_free (gmem.c:252)
   by 0x4F708BF: dbus_watch_set_data (dbus-watch.c:614)
   by 0x4F70938: _dbus_watch_unref (dbus-watch.c:132)
   by 0x4F6E9A7: _dbus_transport_handle_watch (dbus-transport.c:884)
   by 0x4F59AFB: _dbus_connection_handle_watch (dbus-connection.c:1497)
   by 0x4F70AF9: dbus_watch_handle (dbus-watch.c:683)
   by 0x121084: watch_func (mainloop.c:103)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
2025-12-15 18:24:06 +08:00
Jaganath Kanakkassery 3ddfc598f9 gdbus: Fix compilation error if macro "error" is defined
The variable "signature" used in error is not defined and "args" is now
a struct instead of a string.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 51203d47e4 gdbus: Fix removal of filter after last filter_data
If there's a signal watch that's also watching for name
(data->name_watch) currently we are trying to remove the message_filter
twice since we may have the following call chain:

filter_data_remove_callback()
  filter_data_free()
    g_dbus_remove_watch()
      filter_data_remove_callback()
	filter_data_free()
        dbus_connection_remove_filter()
  dbus_connection_remove_filter()

Because of this we can't currently watch for signals passing the bus
name. After this patch we don't have this issue anymore.

We fix it by removing the filter before calling filter_data_free() if we
are the last filter_data and thus avoid calling
dbus_connection_remove_filter() twice.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 4b10a2cfe5 gdbus: add macro for methods marked as NOREPLY 2025-12-15 18:24:06 +08:00
Mikel Astiz 71f621a95c gdbus: Fix incorrectly disspecific productded signals
Signals with no arguments were incorrectly filtered out due to the NULL
inequality check.
2025-12-15 18:24:06 +08:00
Lucas De Marchi a7c003c6b7 gdbus: do not check signature twice
Message signature is already checked in generic_message(), so there's no
need to check again in the callback.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 208aefa1ef gdbus: add Method.NoReply annotation in introspection 2025-12-15 18:24:06 +08:00
Lucas De Marchi e29fc301fd gdbus: add Deprecated annotation in introspection 2025-12-15 18:24:06 +08:00
Lucas De Marchi ae55d45e07 gdbus: remove signature and reply from tables 2025-12-15 18:24:06 +08:00
Lucas De Marchi 84b932d339 gdbus: loop over args to check message signature 2025-12-15 18:24:06 +08:00
Lucas De Marchi 9030b519c2 gdbus: use GDBusArgInfo to generate introspection
By using GDBusArgInfo in methods and signals, the introspection
generation is much simpler and we can add each argument name.
2025-12-15 18:24:06 +08:00
Lucas De Marchi 395189ff75 gdbus: add and use helpers for table declarations 2025-12-15 18:24:06 +08:00
Lucas De Marchi beeef8d9cb gdbus: add argument info to methods and signals 2025-12-15 18:24:06 +08:00
Marcel Holtmann 157de75d42 gdbus: Constify introspection method table 2025-12-15 18:24:06 +08:00
Lucas De Marchi 62ebc7d37c gdbus: do not call memset for terminating NUL 2025-12-15 18:24:06 +08:00
Lucas De Marchi 0f0a0dce2d gdbus: return if method signature is malformed 2025-12-15 18:24:06 +08:00
Marcel Holtmann 9e099e075e gdbus: Remove unneeded NEED_DBUS_WATCH_GET_UNIX_FD check 2025-12-15 18:24:06 +08:00
Anderson Lizardo eef1408e83 gdbus: Use destroy callback for service watch
Even though service watches accepted a "destroy" callback, they were
being ignored. This fix properly pass them along so they are called when
the watch is removed.
2025-12-15 18:24:06 +08:00
Syam Sidhardhan 1b68bd5d37 gdbus: Fix white space coding style issue
- corrected the space before '{'
2025-12-15 18:24:06 +08:00
Szymon Janc 9bd8b008c6 Remove unused result variable from g_dbus_pending_success 2025-12-15 18:24:06 +08:00
Grant Erickson b5ceca251a gdbus: Unconditionally remove D-Bus timeouts
Address an issue in which the daemon incorrectly handles D-Bus main
loop timeouts by only removing timeouts that are not enabled when
D-Bus requests a timeout removal.
2025-12-15 18:24:06 +08:00
Daniel Wagner 67de7dd271 gdbus: Remove root node 'name' attribute in introspection
generate_introspection_xml generates the root <node> tags with a
'name' attribute. This seems to be a valid attribute but it is not
consistent with the way the D-Bus daemon generates empty nodes.

For example if we register "/foo/bar", D-Bus daemon will generate for
"/foo" a introspection which looks like this:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <node name="bar"/>
</node>

and generate_introspection_xml generates for "/foo/bar":

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/foo/bar">
</node>

Just don't add the 'name' attribute to the root node.  The GLib
binding for D-Bus does it the same way.
2025-12-15 18:24:06 +08:00
Daniel Wagner 5c72b8193c gdbus: invaldate_parent_data: walk the whole path down
Assume there is only one object registerd at "/". If we add a new
object at "/foo/bar" the introspection of "/" has to be updated. A new
node has to be added at "/".

invalidate_parent_data stops invaldating the whole path because the
boolean return value of dbus_connection_get_object_path_data is used
wrong.

If we get a TRUE just go on down in the path, if FALSE is return
dbus_connection_get_object_path_data has run out of memory.
2025-12-15 18:24:06 +08:00
Marcel Holtmann e9707aca9f gdbus: Update copyright information 2025-12-15 18:24:05 +08:00
Johan Hedberg 919e7b744b gdbus: fix accessing freed callback data
cb->disc_func or cb->conn_func could remove the callback so this needs
to be checked for before continuing processing.
2025-12-15 18:24:05 +08:00
Lucas De Marchi 5d9ea53b75 gdbus: explicitly compare pointers to NULL
This patch was generated by the following semantic patch
(http://coccinelle.lip6.fr/)

// <smpl>
@fix disable is_null,isnt_null1@
expression *E;
@@

- !E
+ E == NULL
// </smpl>
2025-12-15 18:24:05 +08:00
Luiz Augusto von Dentz 1b87eea590 gdbus: fix not handling bus disconnects
We where not dispatching data when a bus disconnects which cause
Disconnected signal to not be processed and thus causing the process to
either not exit or to not trigger callbacks registered with
g_dbus_set_disconnect_function.

To fix this now we always schedule a dispatch which will make sure data
still not processed will make its way to the proper handlers even if
disconnected.
2025-12-15 18:24:05 +08:00
Marcel Holtmann 0a73d922c9 Add support for builtin GDBus security using PolicyKit 2025-12-15 18:24:05 +08:00
Marcel Holtmann f77d9dfee6 Add support for GDBus security action and flags 2025-12-15 18:24:05 +08:00
Marcel Holtmann 242b93d85c Use simpler error callbacks for GDBus security hooks 2025-12-15 18:24:05 +08:00
Marcel Holtmann 57ddacceef Add support for GDBus security handlers 2025-12-15 18:24:05 +08:00
Luiz Augusto von Dentz f96b27a7e5 Fix calling watch callbacks after it has been removed
Pending call should be removed if the watch is removed since the
application no longer expect that to be reached and may already freed the
data associated with it.
2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz fba30b4954 Fix signal watch when a service name is given
The bus name should be resolved when adding a watch by service name since
messages do always come with sender set to owner's bus name, also it
should listen to owner updates since it can change without invalidating
the watch.
2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz 84bde444d7 Do not automatically remove watches for service names
Services can be owned again so it is perfectly fine to keep the watch.
2025-12-15 18:24:05 +08:00
Marcel Holtmann 4a60e27e0f Add printf format attribute for error creation helper 2025-12-15 18:24:05 +08:00
Zhenhua Zhang 3378e10c7c gdbus: Fix memory leak of service_data
Avoid the memory leak of server_data after service_reply has been
called.
2025-12-15 18:24:05 +08:00
Johan Hedberg 799db28a3f Fix parent path introspection data invalidation for multiple levels
In the case that parent path data needs to be invalidated we shouldn't
stop at the immediate parent if it doesn't have our own handler
registered but should continue upwards in the tree until we reach root
or our own handler.
2025-12-15 18:24:05 +08:00
Johan Hedberg b7dbb506b0 Fix memory leak in g_dbus_register_interface 2025-12-15 18:24:05 +08:00
Marcel Holtmann 2cb42ddf36 Make interface callback tables const 2025-12-15 18:24:05 +08:00
Vinicius Costa Gomes 7869a8b0a3 Fix the case when the requested name is already in use
We weren't setting the dbus error in this situation.
2025-12-15 18:24:05 +08:00
Vinicius Costa Gomes b7f18b4658 Fix: a pending call was leaking in check_service
This was triggering an assert inside libdbus when the timeout inside
the leaking pending call expired. The assert said that we were trying
to remove an nonexistent timeout.
2025-12-15 18:24:05 +08:00
Marcel Holtmann 97261500ac Remove unneeded use of status variable 2025-12-15 18:24:05 +08:00
Forrest Zhao 3118967460 Introduce g_dbus_setup_private() to gdbus
g_dbus_setup_private() is used to setup private DBusConnection
2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz 3f2a1322e2 Fix regression when removing watches
filter_data_find return the first data registered in this case so there is
no guarantee that it return the same data as passed to
filter_data_remove_callback which is the one that should be removed.

The fix is to simple cache the connection removing the correct data before
checking if there is any filter left.
2025-12-15 18:24:05 +08:00
Marcel Holtmann 2769107430 Cleanup of D-Bus mainloop integration 2025-12-15 18:24:05 +08:00
Marcel Holtmann 123ea2203f Update copyright information of D-Bus helper library 2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz 21f789b8d7 Fix undefined symbols 2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz ba7aad615c Port gdbus to use g_dbus_add_signal_watch 2025-12-15 18:24:05 +08:00
Luiz Augusto Von Dentz 5ff12d0e8f Add initial implementation of g_dbus_add_signal_watch
With g_dbus_add_signal_watch there is no need to register multiple filters
for dbus nor add matching rules manually.
2025-12-15 18:24:05 +08:00
Daniel Orstadius 02a0d1c308 Fix D-Bus timeout handling
Timeouts should also be removed in the remove_timeout callback in
addition to the timeout_handler_free function. This is how dbus-glib
does it and it seems to prevent crashes in certain situations.
2025-12-15 18:24:05 +08:00
Claudio Takahasi 467c3e623e Fix message handling for autostart.
Current implementation of libdbus Request name is blocking, consequently
the first incomming message that triggered the service autostart is not
being processed properly.
2025-12-15 18:24:05 +08:00
RISKÓ Gergely 2cb8f33a03 gdbus: handle introspection generally in generic_message.
Previously it was a specific case, now introspection is just another
interface, which is always implemented.  It is registered/unregistered
when an object path is referenced first/last.
2025-12-15 18:24:05 +08:00
RISKÓ Gergely 38f7261caa Add introspection interface to the output of introspection calls
This provides better compatibility with some D-Bus clients, such as qdbus.
2025-12-15 18:24:05 +08:00
Marcel Holtmann 5a0ad136bc Switch to a full non-recursive build system 2025-12-15 18:24:04 +08:00
Johan Hedberg 9025385a6e Use NameHasOwner instead of ListNames for name checking 2025-12-15 18:24:04 +08:00
Marcel Holtmann 74035750e2 Fix blocking service watch initial connect handling 2025-12-15 18:24:04 +08:00
Denis Kenzior 2705df8945 Make the parent path invalidateable 2025-12-15 18:24:04 +08:00
Luiz Augusto von Dentz 06c06dc150 Fix crash when calling g_dbus_remove_watch from inside the watch callback. 2025-12-15 18:24:04 +08:00
Luiz Augusto von Dentz 1e5736a769 Fix g_dbus_remove_all_watches to remove all watches for the given connection. 2025-12-15 18:24:04 +08:00
Luiz Augusto von Dentz a0df1f3a4f Fix gdbus watch function not handling multiple dbus connections.
gdbus was only adding a message filter for the very first connection given
by the user, this caused a bug in agent registration since it has a diffent
connection than previous watches it won't detect agent disappearing from the
bus.
2025-12-15 18:24:04 +08:00
Johan Hedberg 5286617d17 Revert "Fix null dereference in gdbus/watch.c"
This reverts commit a963621f4fcbf0251fd65df0992d339278a78052 so that gdbus
updates from obexd can be merged.
2025-12-15 18:24:04 +08:00
Gustavo F. Padovan 7d7f73e130 Fix null dereference in gdbus/watch.c
If name or data->name is null we have a null dereference. Not name and
data->name.
2025-12-15 18:24:04 +08:00
Marcel Holtmann 23c299dc3f Check that interface name is provided 2025-12-15 18:24:04 +08:00
Marcel Holtmann 98d6b5b96d Update copyright information 2025-12-15 18:24:04 +08:00
Raymond Liu 2652feabc2 Check if path is valid before unregistering it 2025-12-15 18:24:04 +08:00
Marcel Holtmann 42bdabbefc Fix issue with signed/unsigned comparison 2025-12-15 18:24:04 +08:00
Marcel Holtmann f8a650ab98 Use tabs for indentation 2025-12-15 18:24:04 +08:00
Marcel Holtmann 95858d5190 Add missing gdbus function declarations 2025-12-15 18:24:04 +08:00
Marcel Holtmann 842be382da Change file headers for D-Bus helper library 2025-12-15 18:24:04 +08:00
Marcel Holtmann e862047d9d Don't expect reply when sending D-Bus messages 2025-12-15 18:24:04 +08:00
Marcel Holtmann 6ac941b099 Add function for checking if a service is present 2025-12-15 18:24:04 +08:00
Marcel Holtmann a1f4514a5a Add g_dbus_add_service_watch() implementation 2025-12-15 18:24:04 +08:00
Marcel Holtmann 06c6a3d60c Fix connection disconnect function 2025-12-15 18:24:04 +08:00
Marcel Holtmann d0507d99dc Change declaration of GDBusWatchFunction 2025-12-15 18:24:04 +08:00
Johan Hedberg 67c13e1b1e Implement support g_dbus_create_error_valist 2025-12-15 18:24:04 +08:00
Marcel Holtmann 13262739f5 Remove g_dbus_unregister_all_interfaces function 2025-12-15 18:24:04 +08:00
Marcel Holtmann 98bf2e3926 Revert wrong listner id counter offset 2025-12-15 18:24:04 +08:00
Marcel Holtmann 262ee738bd Avoid a watch id of 0 2025-12-15 18:24:04 +08:00
Marcel Holtmann 8c1b9c9e6d Move some D-Bus helpers around 2025-12-15 18:24:04 +08:00
Marcel Holtmann 5de73c0ce4 Don't abstract functions that are only used once 2025-12-15 18:24:04 +08:00
Marcel Holtmann 01fad8f214 Remove another unused function 2025-12-15 18:24:04 +08:00
Marcel Holtmann 72a2c6d38d Make helper function static and local 2025-12-15 18:24:04 +08:00
Marcel Holtmann fe3f118681 Remove unused defines 2025-12-15 18:24:04 +08:00
Marcel Holtmann 2b1a7bed35 Don't consider mainloop integration of dbus-glib 2025-12-15 18:24:04 +08:00
Marcel Holtmann 3e7be8ffd5 Remove another obsolete function 2025-12-15 18:24:04 +08:00
Marcel Holtmann 7909aade9c Add proper signal sending helpers 2025-12-15 18:24:03 +08:00
Marcel Holtmann bc04b2b674 Remove obsolete dbus_connection_get_object_user_data function 2025-12-15 18:24:03 +08:00
Marcel Holtmann cd32f0d4c9 Remove object path creation and destroy helpers 2025-12-15 18:24:03 +08:00
Marcel Holtmann 5929f451fd Remove obsolete D-Bus interface helpers 2025-12-15 18:24:03 +08:00
Marcel Holtmann 178caf3bf3 Remove obsolete D-Bus sending helpers 2025-12-15 18:24:03 +08:00
Marcel Holtmann e8004dcc51 Add simple g_dbus_unregister_all_interfaces implementation 2025-12-15 18:24:03 +08:00
Marcel Holtmann 33ddb45199 Add skeleton for g_dbus_unregister_all_interfaces 2025-12-15 18:24:03 +08:00
Marcel Holtmann 82487204bb Remove GDBusDisconnectFunction type 2025-12-15 18:24:03 +08:00
Johan Hedberg c88da8f4fb Change name_listener API to libgdbus watch API 2025-12-15 18:24:03 +08:00
Marcel Holtmann a06c2bf95e Add helpers for sending async replies 2025-12-15 18:24:03 +08:00
Marcel Holtmann 41a68a1704 Add helpers for creating replies 2025-12-15 18:24:03 +08:00
Marcel Holtmann 80a40e4bc1 Fix broken signal checking for new style API 2025-12-15 18:24:03 +08:00
Marcel Holtmann 8c20dd4094 Add helpers for error creation 2025-12-15 18:24:03 +08:00
Marcel Holtmann ae9735d8ec More fixes for the message dispatch handling 2025-12-15 18:24:03 +08:00
Marcel Holtmann b0842bfd31 Add new message dispatching 2025-12-15 18:24:03 +08:00
Marcel Holtmann c008c770d3 Fix object path reference count handling 2025-12-15 18:24:03 +08:00
Marcel Holtmann 3645f00aec Add introspection support for new interface handlers 2025-12-15 18:24:03 +08:00
Marcel Holtmann 7aebce13e4 Use reference counting for the object paths 2025-12-15 18:24:03 +08:00
Marcel Holtmann 4e2ff8a42d Add first implementation of libgdbus interface helpers 2025-12-15 18:24:03 +08:00
Marcel Holtmann b8094a462a Add prototypes for interface registration 2025-12-15 18:24:03 +08:00
Marcel Holtmann fa8baad6b0 Add real libgdbus types for interface definitions 2025-12-15 18:24:03 +08:00
Marcel Holtmann 5cc51c7078 Move D-Bus object and interface helpers into libgdbus 2025-12-15 18:24:03 +08:00
Marcel Holtmann a34894b7da Move D-Bus watch functions into libgdbus 2025-12-15 18:24:03 +08:00
Marcel Holtmann aca2ce7cb6 Emulate libgdbus API for mainloop integration 2025-12-15 18:24:03 +08:00
Marcel Holtmann 1c4c651c63 Move D-Bus mainloop integration into libgdbus 2025-12-15 18:24:03 +08:00
Marcel Holtmann a446318b57 Add skeleton for libgdbus support 2025-12-15 18:24:03 +08:00
Marcel Holtmann 011f5c8ca9 Add directory for libgdbus library 2025-12-15 18:24:03 +08:00
openvela-robot 1635c81efd 3dde8c07998f0c9c7f9689495eb2690cc3f5a924
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:03 +08:00
openvela-robot 68f7fd9961 kvdb/client: fix monitor fd leak
Signed-off-by: chao an <anchao@xiaomi.com>
2025-12-15 18:24:03 +08:00
Xiang Xiao fcdaa0a743 utils: Add the basic android header files
include/android/log.h:
include/log/:
include/private/android_logger.h
  system/logging/

include/android/set_abort_message.h:
  bionic/libc/include/android/set_abort_message.h

include/cutils/trace.h:
  system/core/libcutils/include/cutils/trace.h

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:02 +08:00
Xiang Xiao cf50ea1eca Add include to the public search path
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:02 +08:00
jihandong 1905297463 frameworks: rm app_focus
dependson:888406

Signed-off-by: jihandong <jihandong@xiaomi.com>
2025-12-15 18:24:02 +08:00
Xiang Xiao 735198da58 Revert "Add include to the public search path"
This reverts commit 26be12ebd2f669d38782ca3911c225e9f2a0644d.
2025-12-15 18:24:02 +08:00
Xiang Xiao b604114074 gdbus: remove glib header file from gdbus.h
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:02 +08:00
Xiang Xiao 9e0274a552 Revert "framework/gdbus: remove glib header file from gdbus.h"
This reverts commit 611fddab6fa2c183170a14811206546df6e6728f.
2025-12-15 18:24:02 +08:00
openvela-robot 0753f3b855 Add include to the public search path
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:02 +08:00
ligd 5b5962d868 kvdb: handle server refused by backlog limitation
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:02 +08:00
openvela-robot 0675feaf6b kvdb: add kvdb xx_oneway API
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:02 +08:00
dongjiuzhu1 e1d9aaa3cd framework/gdbus: using LIB_DBUS to replace DBUS_HELPER_LIBRARY
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:02 +08:00
dongjiuzhu1 019fc1bef7 framework/gdbus: remove glib header file from gdbus.h
Change gboolean to bool, guint to unsigned int, guint32 to uint32_t

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:02 +08:00
dongjiuzhu1 fe905a310f framework/gdbus: remove prefix g_ for gdbus api.
1. Remove prefix g_ for all gdbus api
2. Using macro to compatible g_ gdus api

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:02 +08:00
openvela-robot 35a9155688 framework/gdbus: initial version for D-Bus heleper library
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:02 +08:00
wangbowen6 7de89c5f72 client: bug fix, should assgin '\0' to newvalue[0] instead newvalue
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:01 +08:00
wangbowen6 0511bb8de6 kvdb: [bug fix] memory use after free and ret should be signd num
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:01 +08:00
wangbowen6 a9633d030d kvdb: add kvdb monitor support
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot e2c7c43f3a kvdb: fix property_list exit early problem
when the kvdb has too many kv pairs, after kvdb_list_consume()
blocked in sendmsg (write buffer not enough), the domain socket
buffer layout may became:
[k0_len][v0_len][k0][v0]...[kn_len][vn_len][kn][vn][the last char]
so the client property_list will receive only one char (ret = 1)
after received [k0, v0] ~ [kn, vn], but actually the property list
is not terminated, property_list exit early problem happened.

this problem can be easily reproduced in 86panel by running kvdb
testcase twice.

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot abf21c6560 frameworks/utils: move bin path to apps/staging
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot a9549ca708 frameworks/kvdb: move bin path to apps/staging
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot f69f1f4058 frameworks/utils: create bin to current directory
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot fe0392a514 frameworks/kvdb: create bin to current directory
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
openvela-robot 4f187d2f88 utils: build utils lib into vendor/bes/boards.. from source for m0
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
haopengxiang bc28e21cec kvdb: build kvdb libs into vendor/bes/boards.. from source for m0
Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:01 +08:00
Peter Bee d83d25d538 frameworks/kvdb: unify sizeof() usage
... in hope for eliminating suspicion from CodeChecker

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:24:01 +08:00
wangbowen6 516727006b client: property_set/get_buffer() bug fix
loop condition error

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
2025-12-15 18:24:00 +08:00
Xiang Xiao 15a721ddc3 Move kbdb.h to include directory
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
Peter Bee 62985d3573 frameworks/kvdb: fix getprop long kv fail on sim
Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:24:00 +08:00
chao.an 7747bb4f1d external: move nuttx role files uppper to external
Signed-off-by: chao.an <anchao@xiaomi.com>
2025-12-15 18:24:00 +08:00
Xiang Xiao 1566a11c50 frameworks/kvdb: add property_set_buffer and property_get_buffer
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
Jiuzhu Dong 01e0658403 frameworks/kvdb: using CLOCK_MONOTONIC to avoid time sync
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
2025-12-15 18:24:00 +08:00
huxiandong 4c2e61e80d kvdb: fix read first path error.
Signed-off-by: huxiandong <huxiandong@xiaomi.com>
2025-12-15 18:24:00 +08:00
ligd cf2916d758 kvdb: fix kvdb error modify const data
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:00 +08:00
ligd 367c91fc06 kvdb: fix kvdb error modify const data
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:00 +08:00
ptr_b 60fb6dfb4e frameworks/kvdb: update desc to doxygen style
Signed-off-by: ptr_b <bijunda1@xiaomi.com>
2025-12-15 18:24:00 +08:00
Peter Bee dc7db12af0 frameworks/kvdb: enhance checks
fix Coverity warnings:
check key != NULL (NULL pointer dereference)
check recv length (overrun buffer arg)

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:24:00 +08:00
ligd 2c9d3acbe9 kvdb: remove kvdb list thread
dependson:818316

For list thread will caused mulit-threads access same list of
mem_hash_cursor, if one do the list, other one do delete, then
there will be error.

The typical app is:
call kvdb_delete in kvdb_list callback

Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:24:00 +08:00
Xiang Xiao 527357081b Fix server.c:127:9: warning: argument 1 null where non-null expected
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
chao.an 759578bc75 kvdb/client: fix reload/commit fd leak
Signed-off-by: chao.an <anchao@xiaomi.com>
2025-12-15 18:24:00 +08:00
chao.an 53728ddd40 kvdb/server: reassemble received data to ensure consistency
Signed-off-by: chao.an <anchao@xiaomi.com>
2025-12-15 18:24:00 +08:00
openvela-robot 669702b0c9 fix: optimize default load multi kvdb source files
Signed-off-by: huxiandong <huxiandong@xiaomi.com>
2025-12-15 18:24:00 +08:00
haopengxiang 9266e989fa app focus: add focus_customize value in focus_id for user
1. add focus_customize in focus_id struct
2. extend app_focus_stack_display for more details

Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
haopengxiang 9b78ad0301 app focus: basic module for different focus frameworks
update config description and use list_node as head node

Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
haopengxiang 9c39af1525 Revert "app focus: use list_node as head node"
This reverts commit 6c4b115af4577cbae027b70d09be8af1214e4745.

Reason for revert: Kconfig needs to be updated
2025-12-15 18:24:00 +08:00
openvela-robot 2eddade7d5 app focus: use list_node as head node
remove only interface app_focus_request for method simplification.

Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
2025-12-15 18:24:00 +08:00
liuhaitao 5241de2d4a kvdb: support load from multiple source pathes
Use semicolon ';' to split source pathes. For example,
/etc/build.prop;/misc/factory.prop

Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
2025-12-15 18:23:59 +08:00
chentao9 ba0571ffb8 refactor: kvdb: add force sync flag for kvdb load
1.for kvdb init,do not need force sync existed kv
2.for property_reload api,it will force sync existed kv

Signed-off-by: chentao9 <chentao9@xiaomi.com>
2025-12-15 18:23:59 +08:00
chentao9 28d41782a7 feature: kvdb: add initial value reload support
if the initial value file has been modified,use api 'propprop_reload' to refresh initial value of kvdb

Signed-off-by: chentao9 <chentao9@xiaomi.com>
2025-12-15 18:23:59 +08:00
liuhaitao 092482fe02 kvdb: increases kvdb default stack size from 2K to 4K
Kvdbd server should use 4K stack size to work.

Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
2025-12-15 18:23:59 +08:00
ligd c7dffc852d kvdb: recv should handle return 0 in property_list()
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:23:59 +08:00
ligd 80ed6b0d64 kvdb: simplify KVDB marco in Kconfig
Signed-off-by: ligd <liguiding1@xiaomi.com>
2025-12-15 18:23:59 +08:00
liuhaitao 7e5c08654b kvdb: correct to use PROP_VALUE_MAX for property value
Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
2025-12-15 18:23:59 +08:00
Xiang Xiao d7fe92f930 kvdb: extend the length of name and value to 127 and 255
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:23:59 +08:00
Xiang Xiao 256942fb22 kvdb: handle name or value length beyond 128 correctly
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:23:59 +08:00
openvela-robot d01f202cfa frameworks/kvdb: fix recv() logic in property_list
Fix handling logic when local socket pipe is full, server is
blocked and client does not receive the whole message. The client now
waits for the whole message to be received instead of disspecific productding it and
continue, which will break the communication afterwards.

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:59 +08:00
openvela-robot afbe799688 Initial empty repository 2025-12-15 18:23:59 +08:00
zhanghu b2ae794dd7 kvdb warning: suggest parentheses 2025-12-15 18:23:59 +08:00
Xiang Xiao b6ace1c58d frameworks/kvdb: Add Android compatible header file
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:23:59 +08:00
Peter Bee ef183f04cd frameworks/kvdb: add -h argument for help
N/A

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:59 +08:00
Peter Bee 97df2e7fd1 frameworks/kvdb: add remote server support
N/A

Enable rpmsg socket support for AMP use case

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:59 +08:00
Peter Bee 3ce85f5126 frameworks/kvdb: add API for actively commit props
N/A
add property_commit() to skip commit intervals

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:59 +08:00
chao.an 07bb08198c kvdb: include able from cxx files
Signed-off-by: chao.an <anchao@xiaomi.com>
2025-12-15 18:23:59 +08:00
Peter Bee 0f4991d813 frameworks/kvdb: fix read-only properties init
N/A

Now read-only properties init as expected

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
openvela-robot 6ad14e6c29 Merge "commit the change after loading" into dev 2025-12-15 18:23:58 +08:00
Xiang Xiao f74fed702c commit the change after loading
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 432ec45fb8 frameworks/kvdb: disable journal to accelerate
Disabling unqlite journal, now periodical commit() works as desired

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 9371145001 frameworks/kvdb: load default values if not set
N/A

Load default values depending on whether the value has been set or not,
instead of whether the whole db has existed.

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 8c92342a7f frameworks/kvdb: fix list only list 1 persist prop
N/A

Unqlite expect data consumer to return 0, otherwise it will return
UNQLITE_CORRUPT(-10), which resulted in previous getprop only listing
one persistent property.

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 930be27403 frameworks/kvdb: fix build break
N/A

fix include sys/time.h

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee f0cc12c0b1 frameworks/kvdb: add kvdb server version
add background kvdb server task to speed up I/Os
use unix domain socket for IPC (currently SOCK_STREAM)
add background auto commit interval by select()
use individual thread for property_list

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
chao.an 4c47526729 kvdb: add NULL default value support
N/A

Signed-off-by: chao.an <anchao@xiaomi.com>
2025-12-15 18:23:58 +08:00
Xiang Xiao 6d996e1a1e kvdb: try property_get from environment variable first
N/A

will hook property_list later once get_environ_ptr get implemented

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-12-15 18:23:58 +08:00
liuhaitao 46fe2cbddc kvdb: make ro.* properties modified and deleted not permitted
N/A

Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
2025-12-15 18:23:58 +08:00
liuhaitao 81e2c85dab frameworks/kvdb: update persist.* props behaviour
N/A

persist.* props saved into /data/kv.db instead of using
/persist/kv.db. And all other props saved into /tmp/kv.db.
And all in-memory and user databases default values read
from /etc/build.prop in uniform.

Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 15bcd284b9 frameworks/kvdb: fix property_list return value
Add logic to return -ENOSPC when failed to open all databases.

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee c84a1c15df frameworks/kvdb: fix cli ret judge logic
N/A

property_get error case is when ret==strlen(default_value), not ret < 0

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
Peter Bee 91cdf35900 framework/kvdb: Add kvdb APIs and CLI tools
APIs for setting and getting Key-Value pairs
	CLI tools for command line debugging
	changed API to Android style

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
2025-12-15 18:23:58 +08:00
12 changed files with 60 additions and 7061 deletions

View File

@ -37,7 +37,6 @@ framework_utils_cc_defaults {
cflags: [
"-fvisibility=hidden",
"-DCONFIG_NET_RPMSG",
],
soong_config_variables: {

View File

@ -102,13 +102,12 @@ if !KVDB_DIRECT
config KVDB_SERVER_CPUNAME
string "which cpu kvdb server runs on"
depends on NET_RPMSG
depends on !KVDB_SERVER
default "ap"
config KVDB_TIMEOUT_INTERVAL
int "transaction timeout interval(usec)"
default 5000000
depends on NET_SOCKOPTS
int "transaction timeout interval(sec)"
default 0
endif
@ -120,7 +119,7 @@ config KVDB_COMMIT_INTERVAL
config KVDB_BACKLOG_CONNS
int "backlog connections"
depends on KVDB_SERVER
default 256
default 32
if KVDB_DIRECT || KVDB_SERVER

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +0,0 @@
/*
* Copyright (c) 2024 Xiaomi Technologies Co., Ltd.
* All rights reserved.
*
* This file is part of the Xiaomi project.
*
* This source code is licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <uv_ext.h>
#include <dbus/dbus.h>
#include <dbus/dbus-hash.h>
#include "syslog.h"
#include "gdbus.h"
#define error(fmt, ...) \
do { \
syslog(LOG_ERR, fmt, ##__VA_ARGS__); \
} while (0)
#define warning(fmt, ...) \
do { \
syslog(LOG_WARNING, fmt, ##__VA_ARGS__); \
} while (0)
#define info(fmt, ...) \
do { \
syslog(LOG_INFO, fmt, ##__VA_ARGS__); \
} while (0)
#define debug(fmt, ...) \
do { \
syslog(LOG_DEBUG, fmt, ##__VA_ARGS__); \
} while (0)
struct GDBusClient {
int ref_count;
DBusConnection* dbus_conn;
char* service_name;
char* base_path;
char* root_path;
guint watch;
guint added_watch;
guint removed_watch;
struct ptr_array* match_rules;
DBusPendingCall* pending_call;
DBusPendingCall* get_objects_call;
GDBusWatchFunction connect_func;
void* connect_data;
GDBusWatchFunction disconn_func;
gboolean connected;
void* disconn_data;
GDBusMessageFunction signal_func;
void* signal_data;
GDBusProxyFunction proxy_added;
GDBusProxyFunction proxy_removed;
GDBusProxyPropertyFilterFunction proxy_property_filter;
GDBusProxyFilterFunction proxy_filter;
GDBusClientFunction ready;
void* ready_data;
gboolean ready_called;
GDBusPropertyFunction property_changed;
void* user_data;
DBusList* proxy_list;
gboolean standard;
gboolean getting_object_call;
uv_async_queue_t async_queue;
uv_thread_t main_thread;
GDBusWatch *watcher;
};
struct GDBusProxy {
int ref_count;
GDBusClient* client;
char* obj_path;
char* interface;
DBusHashTable* prop_list;
guint watch;
guint watch_non_standard;
GDBusPropertyFunction prop_func;
void* prop_data;
GDBusProxyFunction removed_func;
void* removed_data;
DBusPendingCall* get_all_call;
gboolean pending;
gboolean filter_first;
gboolean getting_all_prop;
};
GDBusWatch* new_dbus_watch(DBusConnection* connection);
void free_dbus_watch(GDBusWatch* watcher);
void dbus_watch_set_connection_state(GDBusWatch* watcher, gboolean closed);
int dbus_polkit_check_authorization(DBusConnection* conn,
const char* action, gboolean allow_interaction,
void (*callback)(dbus_bool_t, void*),
void* user_data, int timeout_ms);

View File

@ -1,964 +0,0 @@
/*
* Copyright (c) 2024 Xiaomi Technologies Co., Ltd.
* All rights reserved.
*
* This file is part of the Xiaomi project.
*
* This source code is licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __GDBUS_H
#define __GDBUS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <dbus/dbus.h>
typedef void* gpointer;
typedef int gboolean;
typedef unsigned int guint;
typedef uint32_t guint32;
#define g_dbus_setup_bus dbus_setup_bus
#define g_dbus_setup_private dbus_setup_private
#define g_dbus_request_name dbus_request_name
#define g_dbus_set_flags dbus_set_flags
#define g_dbus_get_flags dbus_get_flags
#define g_dbus_register_interface dbus_register_interface
#define g_dbus_unregister_interface dbus_unregister_interface
#define g_dbus_register_security dbus_register_security
#define g_dbus_unregister_security dbus_unregister_security
#define g_dbus_pending_success dbus_pending_success
#define g_dbus_pending_error dbus_pending_error
#define g_dbus_pending_error_valist dbus_pending_error_valist
#define g_dbus_create_error dbus_create_error
#define g_dbus_create_error_valist dbus_create_error_valist
#define g_dbus_create_reply dbus_create_reply
#define g_dbus_create_reply_valist dbus_create_reply_valist
#define g_dbus_send_message dbus_send_message
#define g_dbus_send_message_with_reply dbus_send_message_with_reply
#define g_dbus_send_error dbus_send_error
#define g_dbus_send_error_valist dbus_send_error_valist
#define g_dbus_send_reply dbus_send_reply
#define g_dbus_send_reply_valist dbus_send_reply_valist
#define g_dbus_emit_signal dbus_emit_signal
#define g_dbus_emit_signal_valist dbus_emit_signal_valist
#define g_dbus_pending_property_success dbus_pending_property_success
#define g_dbus_pending_property_error_valist dbus_pending_property_error_valist
#define g_dbus_pending_property_error dbus_pending_property_error
#define g_dbus_emit_property_changed dbus_emit_property_changed
#define g_dbus_emit_property_changed_full dbus_emit_property_changed_full
#define g_dbus_get_properties dbus_get_properties
#define g_dbus_attach_object_manager dbus_attach_object_manager
#define g_dbus_detach_object_manager dbus_detach_object_manager
#define g_dbus_proxy_new dbus_proxy_new
#define g_dbus_proxy_ref dbus_proxy_ref
#define g_dbus_proxy_unref dbus_proxy_unref
#define g_dbus_proxy_get_path dbus_proxy_get_path
#define g_dbus_proxy_get_interface dbus_proxy_get_interface
#define g_dbus_proxy_get_property dbus_proxy_get_property
#define g_dbus_proxy_get_property_basic dbus_proxy_get_property_basic
#define g_dbus_proxy_get_property_iter_cb dbus_proxy_get_property_iter_cb
#define g_dbus_proxy_lookup dbus_proxy_lookup
#define g_dbus_proxy_path_lookup dbus_proxy_path_lookup
#define g_dbus_proxy_refresh_property dbus_proxy_refresh_property
#define g_dbus_proxy_set_property_basic dbus_proxy_set_property_basic
#define g_dbus_proxy_set_property_array dbus_proxy_set_property_array
#define g_dbus_dict_append_entry dbus_dict_append_entry
#define g_dbus_dict_append_basic_array dbus_dict_append_basic_array
#define g_dbus_dict_append_array dbus_dict_append_array
#define g_dbus_proxy_method_call dbus_proxy_method_call
#define g_dbus_proxy_set_property_watch dbus_proxy_set_property_watch
#define g_dbus_proxy_remove_property_watch dbus_proxy_remove_property_watch
#define g_dbus_proxy_set_removed_watch dbus_proxy_set_removed_watch
#define g_dbus_client_new dbus_client_new
#define g_dbus_client_new_full dbus_client_new_full
#define g_dbus_client_ref dbus_client_ref
#define g_dbus_client_unref dbus_client_unref
#define g_dbus_client_set_connect_watch dbus_client_set_connect_watch
#define g_dbus_client_set_disconnect_watch dbus_client_set_disconnect_watch
#define g_dbus_client_set_signal_watch dbus_client_set_signal_watch
#define g_dbus_client_set_ready_watch dbus_client_set_ready_watch
#define g_dbus_client_set_proxy_handlers dbus_client_set_proxy_handlers
#define g_dbus_client_set_proxy_filter dbus_client_set_proxy_filter
typedef struct GDBusArgInfo GDBusArgInfo;
typedef struct GDBusMethodTable GDBusMethodTable;
typedef struct GDBusSignalTable GDBusSignalTable;
typedef struct GDBusPropertyTable GDBusPropertyTable;
typedef struct GDBusSecurityTable GDBusSecurityTable;
typedef void (*GDBusWatchFunction)(DBusConnection* connection,
void* user_data);
typedef void (*GDBusMessageFunction)(DBusConnection* connection,
DBusMessage* message, void* user_data);
typedef gboolean (*GDBusSignalFunction)(DBusConnection* connection,
DBusMessage* message, void* user_data);
typedef void (*GDBusPropIterFunction)(DBusMessageIter* iter, void* value);
/**
* @brief Set and connect to the specified DBus bus type
*
* @param type the type of DBus bus, which can be DBUS_BUS_SESSION or DBUS_BUS_SYSTEM
* @param name The name of the DBus bus to connect to
* @param error A DBusError structure used to store error information
*
* @return If successful, returns a pointer to DBusConnection; if failed, returns NULL
*/
DBusConnection* dbus_setup_bus(DBusBusType type, const char* name, DBusError* error);
/**
* @brief Set up a private DBus connection
*
* This function is used to set up a private DBus connection. It accepts a DBusBusType
* parameter that specifies the type of connection (session or system), a string parameter
* that is the name of the DBus you want to connect to, and a DBusError pointer to store
* any error information that may occur.
* If the function succeeds, it returns a pointer to a DBusConnection, otherwise it returns NULL.
*
* @param type The type of DBus connection, which can be DBUS_BUS_SESSION or DBUS_BUS_SYSTEM
* @param name The name of the DBus you want to connect to
* @param error A DBusError structure used to store error information
* @return Returns a DBusConnection pointer on success, or NULL on failure
*/
DBusConnection* dbus_setup_private(DBusBusType type, const char* name, DBusError* error);
/**
* @brief Requests a specific D-Bus name on the specified DBus connection.
*
* @param connection Pointer to a DBusConnection object representing the connection for
* which the name is to be requested.
* @param name String of the D-Bus name to be requested.
* @param error Pointer to a DBusError object for storing possible errors that may occur
* during the name request.
*
* @return Returns a gboolean value of TRUE if the request succeeds or a gboolean value
* of FALSE if the request fails.
*/
gboolean dbus_request_name(DBusConnection* connection, const char* name, DBusError* error);
typedef void (*GDBusDestroyFunction)(void* user_data);
typedef DBusMessage* (*GDBusMethodFunction)(DBusConnection* connection,
DBusMessage* message, void* user_data);
typedef gboolean (*GDBusPropertyGetter)(const GDBusPropertyTable* property,
DBusMessageIter* iter, void* data);
typedef guint32 GDBusPendingPropertySet;
typedef void (*GDBusPropertySetter)(const GDBusPropertyTable* property,
DBusMessageIter* value, GDBusPendingPropertySet id,
void* data);
typedef gboolean (*GDBusPropertyExists)(const GDBusPropertyTable* property,
void* data);
typedef guint32 GDBusPendingReply;
typedef void (*GDBusSecurityFunction)(DBusConnection* connection,
const char* action,
gboolean interaction,
GDBusPendingReply pending);
enum GDBusFlags {
G_DBUS_FLAG_ENABLE_EXPERIMENTAL = (1 << 0),
};
enum GDBusMethodFlags {
G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
G_DBUS_METHOD_FLAG_NOREPLY = (1 << 1),
G_DBUS_METHOD_FLAG_ASYNC = (1 << 2),
G_DBUS_METHOD_FLAG_EXPERIMENTAL = (1 << 3),
};
enum GDBusSignalFlags {
G_DBUS_SIGNAL_FLAG_DEPRECATED = (1 << 0),
G_DBUS_SIGNAL_FLAG_EXPERIMENTAL = (1 << 1),
};
enum GDBusPropertyFlags {
G_DBUS_PROPERTY_FLAG_DEPRECATED = (1 << 0),
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL = (1 << 1),
};
enum GDBusSecurityFlags {
G_DBUS_SECURITY_FLAG_DEPRECATED = (1 << 0),
G_DBUS_SECURITY_FLAG_BUILTIN = (1 << 1),
G_DBUS_SECURITY_FLAG_ALLOW_INTERACTION = (1 << 2),
};
enum GDbusPropertyChangedFlags {
G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH = (1 << 0),
};
typedef enum GDBusMethodFlags GDBusMethodFlags;
typedef enum GDBusSignalFlags GDBusSignalFlags;
typedef enum GDBusPropertyFlags GDBusPropertyFlags;
typedef enum GDBusSecurityFlags GDBusSecurityFlags;
typedef enum GDbusPropertyChangedFlags GDbusPropertyChangedFlags;
struct GDBusArgInfo {
const char* name;
const char* signature;
};
struct GDBusMethodTable {
const char* name;
GDBusMethodFunction function;
GDBusMethodFlags flags;
unsigned int privilege;
const GDBusArgInfo* in_args;
const GDBusArgInfo* out_args;
};
struct GDBusSignalTable {
const char* name;
GDBusSignalFlags flags;
const GDBusArgInfo* args;
};
struct GDBusPropertyTable {
const char* name;
const char* type;
GDBusPropertyGetter get;
GDBusPropertySetter set;
GDBusPropertyExists exists;
GDBusPropertyFlags flags;
};
struct GDBusSecurityTable {
unsigned int privilege;
const char* action;
GDBusSecurityFlags flags;
GDBusSecurityFunction function;
};
#define GDBUS_ARGS(args...) \
(const GDBusArgInfo[]) \
{ \
args, { } \
}
#define GDBUS_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function
#define GDBUS_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_ASYNC
#define GDBUS_DEPRECATED_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_DEPRECATED
#define GDBUS_DEPRECATED_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_DEPRECATED
#define GDBUS_EXPERIMENTAL_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_EXPERIMENTAL
#define GDBUS_EXPERIMENTAL_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_EXPERIMENTAL
#define GDBUS_NOREPLY_METHOD(_name, _in_args, _out_args, _function) \
.name = _name, \
.in_args = _in_args, \
.out_args = _out_args, \
.function = _function, \
.flags = G_DBUS_METHOD_FLAG_NOREPLY
#define GDBUS_SIGNAL(_name, _args) \
.name = _name, \
.args = _args
#define GDBUS_DEPRECATED_SIGNAL(_name, _args) \
.name = _name, \
.args = _args, \
.flags = G_DBUS_SIGNAL_FLAG_DEPRECATED
#define GDBUS_EXPERIMENTAL_SIGNAL(_name, _args) \
.name = _name, \
.args = _args, \
.flags = G_DBUS_SIGNAL_FLAG_EXPERIMENTAL
void dbus_set_flags(int flags);
int dbus_get_flags(void);
/**
* @brief Register an interface on the specified DBus connection
*
* This function is used to register an interface on the specified DBus connection.
* It requires the following parameters:
* - connection: DBus connection object
* - path: path of DBus interface
* - name: name of DBus interface
* - methods: a GDBusMethodTable object containing methods of interface
* - signals: a GDBusSignalTable object containing signals of interface
* - properties: a GDBusPropertyTable object containing properties of interface
* - user_data: user data, which can be passed to callback function
* - destroy: a GDBusDestroyFunction, which is called when the interface is deregistered
* to clean up user data
*
* @param connection DBus connection object
* @param path path of DBus interface
* @param name name of DBus interface
* @param methods GDBusMethodTable object containing interface methods
* @param signals GDBusSignalTable object containing interface signals
* @param properties GDBusPropertyTable object containing interface properties
* @param user_data user data
* @param destroy GDBusDestroyFunction for cleaning up user data
* @return gboolean Returns TRUE if registration is successful, and FALSE if fails
*/
gboolean dbus_register_interface(DBusConnection* connection,
const char* path, const char* name,
const GDBusMethodTable* methods,
const GDBusSignalTable* signals,
const GDBusPropertyTable* properties,
void* user_data,
GDBusDestroyFunction destroy);
/**
* @brief Unregister the specified interface from the specified DBus connection
*
* @param connection Pointer to DBusConnection, indicating the DBus connection of the
* interface to be unregistered
* @param path Path of the interface
* @param name Name of the interface
* @return If the interface is successfully unregistered, return gboolean TRUE, otherwise
* return FALSE
*/
gboolean dbus_unregister_interface(DBusConnection* connection,
const char* path, const char* name);
gboolean dbus_register_security(const GDBusSecurityTable* security);
gboolean dbus_unregister_security(const GDBusSecurityTable* security);
void dbus_pending_success(DBusConnection* connection,
GDBusPendingReply pending);
void dbus_pending_error(DBusConnection* connection,
GDBusPendingReply pending,
const char* name, const char* format, ...)
__attribute__((format(printf, 4, 5)));
void dbus_pending_error_valist(DBusConnection* connection,
GDBusPendingReply pending, const char* name,
const char* format, va_list args);
DBusMessage* dbus_create_error(DBusMessage* message, const char* name,
const char* format, ...)
__attribute__((format(printf, 3, 4)));
DBusMessage* dbus_create_error_valist(DBusMessage* message, const char* name,
const char* format, va_list args);
DBusMessage* dbus_create_reply(DBusMessage* message, int type, ...);
DBusMessage* dbus_create_reply_valist(DBusMessage* message,
int type, va_list args);
/**
* @brief Send a message to the specified DBus connection
*
* @param connection Pointer to the DBusConnection object, indicating the DBus connection
* to send the message
* @param message Pointer to the DBusMessage object, indicating the message to send
*
* @return If the sending is successful, return the gboolean type with a value of TRUE;
* if the sending fails, return the gboolean type with a value of FALSE
*/
gboolean dbus_send_message(DBusConnection* connection, DBusMessage* message);
/**
* @brief Send a message to the specified DBus connection and wait for a reply,
* non-blocking call
*
* @param connection Pointer to the DBusConnection object, indicating the DBus connection
* @param message Pointer to the DBusMessage object, indicating the message to be sent
* @param call Pointer to the pointer to the DBusPendingCall object, used to store the
* handle of the asynchronous call
* @param timeout Timeout for waiting for a reply after sending a message, in milliseconds
*
* @return If the message is successfully sent and the DBusPendingCall object instance is
* replied, the return value of the gboolean type is TRUE; otherwise, it returns FALSE
*/
gboolean dbus_send_message_with_reply(DBusConnection* connection, DBusMessage* message,
DBusPendingCall** call, int timeout);
gboolean dbus_send_error(DBusConnection* connection, DBusMessage* message,
const char* name, const char* format, ...)
__attribute__((format(printf, 4, 5)));
gboolean dbus_send_error_valist(DBusConnection* connection,
DBusMessage* message, const char* name,
const char* format, va_list args);
gboolean dbus_send_reply(DBusConnection* connection,
DBusMessage* message, int type, ...);
gboolean dbus_send_reply_valist(DBusConnection* connection,
DBusMessage* message, int type, va_list args);
gboolean dbus_emit_signal(DBusConnection* connection,
const char* path, const char* interface,
const char* name, int type, ...);
gboolean dbus_emit_signal_valist(DBusConnection* connection,
const char* path, const char* interface,
const char* name, int type, va_list args);
typedef struct GDBusWatch GDBusWatch;
/**
* Adds a service watch to monitor the specified D-Bus service name
*
* @param watcher The GDBusWatch instance to add the watch to
* @param name The D-Bus service name to watch (e.g. "org.freedesktop.DBus")
* @param connect Callback function when service connects
* @param disconnect Callback function when service disconnects
* @param user_data User data passed to callbacks
* @param destroy Destroy notification callback for user_data
* @return Watch ID that can be used to remove the watch
*/
guint dbus_add_service_watch(GDBusWatch* watcher, const char* name,
GDBusWatchFunction connect, GDBusWatchFunction disconnect,
void* user_data, GDBusDestroyFunction destroy);
/**
* Adds a disconnect watch for the specified D-Bus name
*
* @param watcher The GDBusWatch instance to add the watch to
* @param name The D-Bus name to monitor for disconnection
* @param function Callback function when name disconnects
* @param user_data User data passed to callback
* @param destroy Destroy notification callback for user_data
* @return Watch ID that can be used to remove the watch
*/
guint dbus_add_service_disconnect_watch(GDBusWatch* watcher, const char* name,
GDBusWatchFunction function, void* user_data, GDBusDestroyFunction destroy);
/**
* @brief Add a signal monitor to the DBus connection
*
* @param connection: Pointer to DBusConnection, indicating the DBus connection to which
* the signal monitor is to be added
* @param sender: The name of the DBus client that sends the signal. If it is NULL, the
* signals of all clients are monitored
* @param path: The path of the signal. If it is NULL, the signals of all paths are
* monitored
* @param interface: The interface of the signal. If it is NULL, the signals of all
* interfaces are monitored
* @param member: The member of the signal, that is, the specific name of the signal.
* If it is NULL, the signals of all members are monitored
* @param function: The function called when the signal is received receives the
* following parameters:
* - DBusConnection*: DBus connection
* - const char*: The sender of the signal
* - const char*: The path of the signal
* - const char*: The interface of the signal
* - const char*: The member of the signal
* - void*: User data
* @param user_data: User data, which will be passed to the function when calling the
* function
* @param destroy: The function called when the signal monitor is removed to destroy
* user_data. If it is NULL, no action is performed.
* @return: Returns an unsigned integer representing the ID of the newly created signal
* monitor.
*/
guint dbus_add_signal_watch(GDBusWatch* watcher,
const char* sender, const char* path,
const char* interface, const char* member,
GDBusSignalFunction function, void* user_data,
GDBusDestroyFunction destroy);
guint dbus_add_properties_watch(GDBusWatch* watcher,
const char* sender, const char* path,
const char* interface,
GDBusSignalFunction function, void* user_data,
GDBusDestroyFunction destroy);
/**
* @brief Remove a specific watch from the specified DBus connection
*
* @param connection Pointer to DBusConnection, indicating the connection from which the
* watch is to be removed
* @param tag Indicates the unique identifier of the watch to be removed
*
* @return gboolean The function returns TRUE if executed successfully, otherwise returns
* FALSE
*/
gboolean dbus_remove_watch(GDBusWatch* watcher, guint tag);
void dbus_remove_all_watches(GDBusWatch* watcher);
void dbus_pending_property_success(GDBusPendingPropertySet id);
void dbus_pending_property_error_valist(GDBusPendingReply id,
const char* name, const char* format, va_list args);
void dbus_pending_property_error(GDBusPendingReply id, const char* name,
const char* format, ...);
/*
* Note that when multiple properties for a given object path are changed
* in the same mainloop iteration, they will be grouped with the last
* property changed. If this behaviour is undesired, use
* dbus_emit_property_changed_full() with the
* G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH flag, causing the signal to ignore
* any grouping.
*/
void dbus_emit_property_changed(DBusConnection* connection,
const char* path, const char* interface,
const char* name);
void dbus_emit_property_changed_full(DBusConnection* connection,
const char* path, const char* interface,
const char* name,
GDbusPropertyChangedFlags flags);
gboolean dbus_get_properties(DBusConnection* connection, const char* path,
const char* interface, DBusMessageIter* iter);
gboolean dbus_attach_object_manager(DBusConnection* connection);
gboolean dbus_detach_object_manager(DBusConnection* connection);
typedef struct GDBusClient GDBusClient;
typedef struct GDBusProxy GDBusProxy;
/**
* @brief Create a new D-Bus proxy object
*
* This function is used to create a new D-Bus proxy object.
*
* @param client Pointer to the GDBusClient object, which is an instance of the
* D-Bus client.
* @param path The path of the D-Bus proxy.
* @param interface The name of the interface to be implemented by the D-Bus proxy.
*
* @return Returns a pointer to the GDBusProxy object if it was created successfully,
* otherwise returns NULL.
*/
GDBusProxy* dbus_proxy_new(GDBusClient* client, const char* path,
const char* interface);
/**
* @brief Increase the reference count of a D-Bus proxy
*
* This function increases the reference count of a given D-Bus proxy.
*
* @param proxy Pointer to the D-Bus proxy whose reference count is to be increased.
* @return Returns the pointer to the D-Bus proxy after the reference count is increased.
*/
GDBusProxy* dbus_proxy_ref(GDBusProxy* proxy);
/**
* @brief Decrement the reference count of a D-Bus proxy
*
* This function decrements the reference count of a given D-Bus proxy. If the reference
* count reaches 0, the proxy will be released.
*
* @param proxy Pointer to the D-Bus proxy whose reference count is to be decremented.
*/
void dbus_proxy_unref(GDBusProxy* proxy);
/**
* @brief Get the path of the D-Bus proxy
*
* @param proxy Pointer to GDBusProxy
* @return Return the path of the proxy
*/
const char* dbus_proxy_get_path(const GDBusProxy* proxy);
/**
* @brief Get the interface of the D-Bus proxy
*
* @param proxy Pointer to GDBusProxy
* @return Return the interface of the proxy
*/
const char* dbus_proxy_get_interface(GDBusProxy* proxy);
/**
* @brief Gets a property value from a D-Bus proxy object, should run
* in uv default loop.
*
* @param proxy The D-Bus proxy object to query
* @param name The name of the property to get
* @param iter Pointer to a DBusMessageIter to store the property value
* @return gboolean TRUE if successful, FALSE otherwise
*
* This function synchronously gets a property value from a D-Bus proxy object
* and stores it in the provided DBusMessageIter. The caller is responsible
* for properly handling the DBusMessageIter contents.
*/
gboolean dbus_proxy_get_property(GDBusProxy* proxy, const char* name,
DBusMessageIter* iter);
/**
* @brief Gets a basic property value from a D-Bus proxy object (thread-safe)
*
* @param proxy The D-Bus proxy object to query
* @param name The name of the property to get
* @param value Pointer to store the property value (must match property type)
* @return gboolean TRUE if successful, FALSE otherwise
*
* This function synchronously gets a basic type property value from a D-Bus
* proxy object in a thread-safe manner. For complex struct properties,
* please use dbus_proxy_get_property_iter_cb instead. The value parameter
* must point to storage of the correct type for the property being retrieved.
*/
gboolean dbus_proxy_get_property_basic(GDBusProxy* proxy, const char* name,
void* value);
/**
* Asynchronously gets a D-Bus proxy property with thread safety
*
* @param proxy The D-Bus proxy object to query
* @param name Name of the property to retrieve
* @param value Pointer to store the property value
* @param iter_cb Callback function to handle property iteration
* @return TRUE if property was successfully retrieved, FALSE on error
*
* @note This function handles thread synchronization automatically.
* It can be called from any thread but will block if not in default loop.
*/
gboolean dbus_proxy_get_property_iter_cb(GDBusProxy* proxy, const char* name,
void* value, GDBusPropIterFunction iter_cb);
GDBusProxy* dbus_proxy_lookup(void* list, int* index, const char* path,
const char* interface);
char* dbus_proxy_path_lookup(void* list, int* index, const char* path);
gboolean dbus_proxy_refresh_property(GDBusProxy* proxy, const char* name);
typedef void (*GDBusResultFunction)(const DBusError* error, void* user_data);
/**
* @brief This function is used to set the properties of a D-Bus proxy.
*
* @param proxy Pointer to GDBusProxy, indicating the proxy to set the properties.
* @param name The name of the property, which should be a string type.
* @param type The type of the property, which should be an integer, indicating the data
* type of the property.
* @param value Pointer to the value of the property, which should be a void type,
* indicating the value of the property.
* @param function Pointer to GDBusResultFunction, indicating the function to be executed
* after setting the property.
* @param user_data Pointer to user data, which will be passed when executing
* the @param function function.
* @param destroy Pointer to GDBusDestroyFunction, indicating how to destroy the data
* pointed to by value when the set property is no longer needed.
*
* @return Returns a true value of type gboolean if the property is successfully set;
* otherwise, returns a false value.
*/
gboolean dbus_proxy_set_property_basic(GDBusProxy* proxy,
const char* name, int type, const void* value,
GDBusResultFunction function, void* user_data,
GDBusDestroyFunction destroy);
gboolean dbus_proxy_set_property_array(GDBusProxy* proxy,
const char* name, int type, const void* value,
size_t size, GDBusResultFunction function,
void* user_data, GDBusDestroyFunction destroy);
void dbus_dict_append_entry(DBusMessageIter* dict,
const char* key, int type, void* val);
void dbus_dict_append_basic_array(DBusMessageIter* dict, int key_type,
const void* key, int type, void* val,
int n_elements);
void dbus_dict_append_array(DBusMessageIter* dict,
const char* key, int type, void* val,
int n_elements);
typedef void (*GDBusSetupFunction)(DBusMessageIter* iter, void* user_data);
typedef void (*GDBusReturnFunction)(DBusMessage* message, void* user_data);
/**
* @brief Calls the specified @method method on the given D-Bus proxy
*
* @param proxy Pointer to GDBusProxy, indicating the D-Bus proxy to be called
* @param method The name of the method to be called
* @param setup A GDBusSetupFunction, used to set the parameters of the method call
* @param function A GDBusReturnFunction, called after the method call succeeds,
* returns the return value of the method
* @param user_data User data, passed to GDBusReturnFunction
* @param destroy A GDBusDestroyFunction, called after the method call is completed,
* used to clean up resources
*
* @return Returns gboolean if the method call succeeds, otherwise returns gboolean
*/
gboolean dbus_proxy_method_call(GDBusProxy* proxy, const char* method,
GDBusSetupFunction setup,
GDBusReturnFunction function, void* user_data,
GDBusDestroyFunction destroy);
typedef void (*GDBusClientFunction)(GDBusClient* client, void* user_data);
typedef void (*GDBusProxyFunction)(GDBusProxy* proxy, void* user_data);
typedef gboolean (*GDBusProxyPropertyFilterFunction)(GDBusProxy* proxy, void* user_data);
typedef void (*GDBusPropertyFunction)(GDBusProxy* proxy, const char* name,
DBusMessageIter* iter, void* user_data);
typedef gboolean (*GDBusProxyFilterFunction)(const char* path,
const char* interface, void* user_data);
/**
* @brief Sets a property monitor for the D-Bus proxy.
*
* @param proxy the GDBusProxy object which the property monitor is to be set.
* @param function Pointer to the callback function that handles property changes.
* @param user_data User data, which will be passed to the callback function.
* @return Returns TRUE if the monitor was successfully set, otherwise returns FALSE.
*/
gboolean dbus_proxy_set_property_watch(GDBusProxy* proxy,
GDBusPropertyFunction function, void* user_data);
/**
* @brief Removes a property monitor from a D-Bus proxy.
*
* @param proxy the GDBusProxy object whose property monitor is to be removed.
* @param destroy Pointer to a destruction function that handles user data.
* @return Returns TRUE if the monitor was successfully removed, otherwise returns FALSE.
*/
gboolean dbus_proxy_remove_property_watch(GDBusProxy* proxy,
GDBusDestroyFunction destroy);
gboolean dbus_proxy_set_removed_watch(GDBusProxy* proxy,
GDBusProxyFunction destroy, void* user_data);
/**
* @brief Create a new DBus client instance
*
* This function is used to create a new DBus client instance.
*
* @param connection Pointer to DBus connection.
* @param service Service name, used to identify DBus service.
* @param path Path, used to identify the path of DBus object.
*
* @return Returns a pointer to the newly created GDBusClient instance.
*/
GDBusClient* dbus_client_new(DBusConnection* connection,
const char* service, const char* path);
GDBusClient* dbus_client_new_full(DBusConnection* connection,
const char* service,
const char* path,
const char* root_path);
/**
* @brief Increase the reference count of the GDBusClient object.
*
* @param client The GDBusClient object whose reference count is to be increased.
* @return The GDBusClient object after the reference count is increased.
*/
GDBusClient* dbus_client_ref(GDBusClient* client);
/**
* @brief Decrement the reference count of a GDBusClient object.
*
* @param client The GDBusClient object whose reference count is to be decremented.
*/
void dbus_client_unref(GDBusClient* client);
/**
* @brief Set the connection monitoring function of the D-Bus client.
*
* @param client Pointer to the GDBusClient instance.
* @param function Pointer to the function of type GDBusWatchFunction, which will be
* called when there is a new D-Bus connection.
* @param user_data caller data, which will be passed to the caller when callback
* @return If the setting is successful, return a true value of type gboolean; otherwise,
* return a false value.
*/
gboolean dbus_client_set_connect_watch(GDBusClient* client, GDBusWatchFunction function,
void* user_data);
/**
* @brief Set the disconnection monitoring function of the D-Bus client.
*
* @param client Pointer to the GDBusClient instance.
* @param function Pointer to the function of type GDBusWatchFunction, which will be
* called when the D-Bus connection is disconnected.
* @param user_data caller data will be passed to the caller when calling the function.
* @return If the setting is successful, return a true value of type gboolean; otherwise,
* return a false value.
*/
gboolean dbus_client_set_disconnect_watch(GDBusClient* client,
GDBusWatchFunction function, void* user_data);
/**
* @brief Set the signal monitoring function of the D-Bus client
*
* This function is used to set the signal monitoring function of the D-Bus client.
* When the client receives a D-Bus signal, the function will be called.
*
* @param client Pointer to the D-Bus client
* @param function Points to the function that processes the D-Bus signal
* @param user_data caller data will be passed to the caller when calling the function
*
* @return If the setting is successful, return gboolean as TRUE, otherwise return FALSE
*/
gboolean dbus_client_set_signal_watch(GDBusClient* client,
GDBusMessageFunction function, void* user_data);
/**
* @brief Set the preparation function and user data of the DBus client
*
* This function is used to set the preparation function and user data of the DBus client.
* The preparation function will be called when the DBus client is ready, and the user
* data can be passed to this function.
*
* @param client Pointer to the DBus client
* @param ready Preparation function, which will be called when the DBus client is ready
* @param user_data User data, which can be passed to the preparation function
*
* @return gboolean If the setting is successful, it returns TRUE, otherwise it returns FALSE
*/
gboolean dbus_client_set_ready_watch(GDBusClient* client,
GDBusClientFunction ready, void* user_data);
/**
* @brief Set the proxy handler function
*
* This function is used to set the proxy handler function of the D-Bus client.
*
* @param client Pointer to the GDBusClient instance.
* @param proxy_added Callback function when the proxy is added.
* @param proxy_removed Callback function when the proxy is removed.
* @param proxy_property_filter Callback function for proxy property filtering.
* @param property_changed Callback function when the property is changed.
* @param user_data caller data, which will be used in the callback function.
* @return If the setting is successful, the return gboolean is TRUE, otherwise
* it returns FALSE.
*/
gboolean dbus_client_set_proxy_handlers(GDBusClient* client,
GDBusProxyFunction proxy_added,
GDBusProxyFunction proxy_removed,
GDBusProxyPropertyFilterFunction proxy_property_filter,
GDBusPropertyFunction property_changed,
void* user_data);
/**
* @brief Set the proxy filter function
*
* This function is used to set the proxy filter function of the D-Bus client.
*
* @param client Pointer to the GDBusClient instance.
* @param proxy_filter Callback function of the proxy filter.
* @param user_data caller data, which will be used in the callback function.
* @return If the setting is successful, the return gboolean is TRUE, otherwise
* it returns FALSE.
*/
gboolean dbus_client_set_proxy_filter(GDBusClient* client,
GDBusProxyFilterFunction proxy_filter,
void* user_data);
/**
* Adds a service watch for the specified name.
* @param client The DBus client instance
* @param name The service name to watch
* @param connect Callback when service connects
* @param disconnect Callback when service disconnects
* @param user_data User data passed to callbacks
* @param destroy Destroy notification callback
* @return Watch ID
*/
guint dbus_client_add_service_watch(GDBusClient* client, const char* name,
GDBusWatchFunction connect, GDBusWatchFunction disconnect,
void* user_data, GDBusDestroyFunction destroy);
/**
* Adds a watch for service disconnection only.
* @param client The DBus client instance
* @param name The service name to watch
* @param function Callback when service disconnects
* @param user_data User data passed to callback
* @param destroy Destroy notification callback
* @return Watch ID
*/
guint dbus_client_add_service_disconnect_watch(GDBusClient* client, const char* name,
GDBusWatchFunction function, void* user_data, GDBusDestroyFunction destroy);
/**
* Adds a signal watch with detailed matching criteria.
* @param client The DBus client instance
* @param sender The sender name to match
* @param path The object path to match
* @param interface The interface name to match
* @param member The member name to match
* @param function Callback when signal is received
* @param user_data User data passed to callback
* @param destroy Destroy notification callback
* @return Watch ID
*/
guint dbus_client_add_signal_watch(GDBusClient* client,const char* sender,
const char* path, const char* interface, const char* member,
GDBusSignalFunction function, void* user_data, GDBusDestroyFunction destroy);
/**
* Adds a properties change watch.
* @param client The DBus client instance
* @param sender The sender name to match
* @param path The object path to match
* @param interface The interface name to match
* @param function Callback when properties change
* @param user_data User data passed to callback
* @param destroy Destroy notification callback
* @return Watch ID
*/
guint dbus_client_add_properties_watch(GDBusClient* client,
const char* sender, const char* path, const char* interface,
GDBusSignalFunction function, void* user_data, GDBusDestroyFunction destroy);
/**
* Removes a previously added watch.
* @param client The DBus client instance
* @param tag The watch ID to remove
* @return TRUE if watch was found and removed
*/
gboolean dbus_client_remove_watch(GDBusClient* client, guint tag);
/**
* Removes all watches from the client.
* @param client The DBus client instance
*/
void dbus_client_remove_all_watches(GDBusClient* client);
/**
* Adds a watch for client disconnection.
* @param client The DBus client instance
* @param function Callback when client disconnects
* @param user_data User data passed to callback
* @param destroy Destroy notification callback
* @return Watch ID
*/
gboolean dbus_client_add_disconnect_watch(GDBusClient* client,
GDBusWatchFunction function, void* user_data, DBusFreeFunction destroy);
#ifdef __cplusplus
}
#endif
#endif /* __GDBUS_H */

View File

@ -1,512 +0,0 @@
/*
* Copyright (c) 2024 Xiaomi Technologies Co., Ltd.
* All rights reserved.
*
* This file is part of the Xiaomi project.
*
* This source code is licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dbus/dbus.h>
#include <poll.h>
#include <stdlib.h>
#include <uv.h>
#include "gdbus-internal.h"
struct idle_handler {
uv_idle_t handle;
DBusConnection* conn;
};
struct timeout_handler {
uv_timer_t handle;
DBusTimeout* timeout;
};
struct dbus_watch_info {
uv_poll_t* handle;
DBusWatch* read_watch;
DBusWatch* write_watch;
DBusConnection* conn;
};
static void close_cb(uv_handle_t* handle)
{
free(handle->data);
}
static void message_dispatch(uv_idle_t* handle)
{
struct idle_handler* handler = handle->data;
DBusConnection* conn = handler->conn;
/* Dispatch messages */
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS)
;
dbus_connection_unref(conn);
uv_close((uv_handle_t*)handle, close_cb);
}
static inline void queue_dispatch(DBusConnection* conn,
DBusDispatchStatus status)
{
if (status == DBUS_DISPATCH_DATA_REMAINS) {
struct idle_handler* handler;
handler = calloc(1, sizeof(struct idle_handler));
if (handler == NULL) {
return;
}
if (uv_idle_init(uv_default_loop(), &handler->handle) != 0) {
free(handler);
return;
}
handler->conn = dbus_connection_ref(conn);
handler->handle.data = handler;
if (uv_idle_start(&handler->handle, message_dispatch) != 0) {
dbus_connection_unref(conn);
uv_close((uv_handle_t*)&handler->handle, close_cb);
free(handler);
}
}
}
static void watch_func(uv_poll_t* handle, int state, int events)
{
struct dbus_watch_info* info = handle->data;
unsigned int flags = 0;
DBusDispatchStatus status;
DBusConnection* conn;
if (events & UV_READABLE)
flags |= DBUS_WATCH_READABLE;
if (events & UV_WRITABLE)
flags |= DBUS_WATCH_WRITABLE;
if (events & UV_DISCONNECT)
flags |= DBUS_WATCH_HANGUP;
if (events & POLLERR)
flags |= DBUS_WATCH_ERROR;
/* Protect connection from being destroyed by dbus_watch_handle */
conn = dbus_connection_ref(info->conn);
if (flags & DBUS_WATCH_READABLE && info->read_watch != NULL)
dbus_watch_handle(info->read_watch, flags);
if (flags & DBUS_WATCH_WRITABLE && info->write_watch != NULL)
dbus_watch_handle(info->write_watch, flags);
status = dbus_connection_get_dispatch_status(conn);
queue_dispatch(conn, status);
dbus_connection_unref(conn);
}
static void close_watch_info_handler_cb(uv_handle_t* handle)
{
struct dbus_watch_info* info = handle->data;
if (info == NULL)
return;
if (info->read_watch) {
dbus_watch_set_data(info->read_watch, NULL, NULL);
info->read_watch = NULL;
}
if (info->write_watch) {
dbus_watch_set_data(info->write_watch, NULL, NULL);
info->write_watch = NULL;
}
free(info->handle);
info->handle = NULL;
}
static void watch_info_free_read(void* data)
{
struct dbus_watch_info* info = data;
if (info != NULL && info->read_watch != NULL) {
info->read_watch = NULL;
/**
* libdbus maybe call read watch free cb, not from remove watch.
* need close uv hander when read and watch both null.
*/
if (info->write_watch == NULL && info->handle != NULL)
uv_close((uv_handle_t*)info->handle, close_watch_info_handler_cb);
}
}
static void watch_info_free_write(void* data)
{
struct dbus_watch_info* info = data;
if (info != NULL && info->write_watch != NULL) {
info->write_watch = NULL;
/**
* libdbus maybe call write watch free cb, not from remove watch.
* need close uv hander when read and watch both null.
*/
if (info->read_watch == NULL && info->handle != NULL)
uv_close((uv_handle_t*)info->handle, close_watch_info_handler_cb);
}
}
static dbus_bool_t add_watch(DBusWatch* watch, void* data)
{
struct dbus_watch_info* watch_info = data;
int cond = UV_DISCONNECT;
int flags = 0;
if (!dbus_watch_get_enabled(watch))
return TRUE;
flags = dbus_watch_get_flags(watch);
if (flags & DBUS_WATCH_READABLE) {
dbus_watch_set_data(watch, watch_info, watch_info_free_read);
watch_info->read_watch = watch;
}
if (flags & DBUS_WATCH_WRITABLE) {
dbus_watch_set_data(watch, watch_info, watch_info_free_write);
watch_info->write_watch = watch;
}
if (watch_info->read_watch != NULL && watch != watch_info->read_watch)
flags |= dbus_watch_get_flags(watch_info->read_watch);
if (watch_info->write_watch != NULL && watch != watch_info->write_watch)
flags |= dbus_watch_get_flags(watch_info->write_watch);
if (flags & DBUS_WATCH_READABLE)
cond |= UV_READABLE;
if (flags & DBUS_WATCH_WRITABLE)
cond |= UV_WRITABLE;
if (!watch_info->handle) {
watch_info->handle = calloc(1, sizeof(uv_poll_t));
if (!watch_info->handle)
return FALSE;
int fd = dbus_watch_get_unix_fd(watch);
if (uv_poll_init(uv_default_loop(), watch_info->handle, fd) != 0) {
free(watch_info->handle);
watch_info->handle = NULL;
dbus_watch_set_data(watch, NULL, NULL);
return FALSE;
}
watch_info->handle->data = watch_info;
}
if (uv_poll_start(watch_info->handle, cond, watch_func) != 0) {
uv_close((uv_handle_t*)watch_info->handle, close_watch_info_handler_cb);
return FALSE;
}
return TRUE;
}
static void remove_watch(DBusWatch* watch, void* data)
{
int flags = 0;
int cond = 0;
struct dbus_watch_info* info = data;
/* If the watch is still enabled, we treat this as a toggle */
if (dbus_watch_get_enabled(watch))
return;
if (info->read_watch == watch && info->write_watch != NULL) {
/* remove watch is read, keep write flag if write watch is valid */
flags = dbus_watch_get_flags(info->write_watch);
} else if (info->write_watch == watch && info->read_watch != NULL) {
/* remove watch is write, keep read flag if read watch is valid */
flags = dbus_watch_get_flags(info->read_watch);
}
if (flags & DBUS_WATCH_READABLE)
cond |= UV_READABLE;
if (flags & DBUS_WATCH_WRITABLE)
cond |= UV_WRITABLE;
if (cond != 0) {
cond |= UV_DISCONNECT;
if (uv_poll_start(info->handle, cond, watch_func) != 0) {
uv_close((uv_handle_t*)info->handle, close_watch_info_handler_cb);
return;
}
}
/* will trigger watch_info_free_read/write() */
dbus_watch_set_data(watch, NULL, NULL);
}
static void watch_toggled(DBusWatch* watch, void* data)
{
/* Because we just exit on OOM, enable/disable is
* no different from add/remove */
if (dbus_watch_get_enabled(watch))
add_watch(watch, data);
else
remove_watch(watch, data);
}
static void timeout_handler_dispatch(uv_timer_t* handle)
{
struct timeout_handler* handler = handle->data;
/* if not enabled should not be polled by the main loop */
if (dbus_timeout_get_enabled(handler->timeout))
dbus_timeout_handle(handler->timeout);
}
static void timeout_handler_free(void* data)
{
struct timeout_handler* handler = data;
uv_close((uv_handle_t*)&handler->handle, close_cb);
}
static dbus_bool_t add_timeout(DBusTimeout* timeout, void* data)
{
int interval = dbus_timeout_get_interval(timeout);
struct timeout_handler* handler;
if (!dbus_timeout_get_enabled(timeout))
return TRUE;
handler = calloc(1, sizeof(struct timeout_handler));
if (handler == NULL)
return FALSE;
handler->timeout = timeout;
dbus_timeout_set_data(timeout, handler, timeout_handler_free);
if (uv_timer_init(uv_default_loop(), &handler->handle) != 0) {
goto errout;
}
handler->handle.data = handler;
if (uv_timer_start(&handler->handle, timeout_handler_dispatch, interval, 0) != 0) {
uv_close((uv_handle_t*)&handler->handle, close_cb);
goto errout;
}
return TRUE;
errout:
free(handler);
dbus_timeout_set_data(timeout, NULL, NULL);
return FALSE;
}
static void remove_timeout(DBusTimeout* timeout, void* data)
{
/* will trigger timeout_handler_free() */
dbus_timeout_set_data(timeout, NULL, NULL);
}
static void timeout_toggled(DBusTimeout* timeout, void* data)
{
if (dbus_timeout_get_enabled(timeout))
add_timeout(timeout, data);
else
remove_timeout(timeout, data);
}
static void dispatch_status(DBusConnection* conn,
DBusDispatchStatus status, void* data)
{
if (!dbus_connection_get_is_connected(conn))
return;
queue_dispatch(conn, status);
}
static void dbus_watch_info_free(void* data)
{
struct dbus_watch_info* info = data;
if (info != NULL) {
dbus_connection_unref(info->conn);
free(info);
}
}
static inline void setup_dbus_with_main_loop(DBusConnection* conn)
{
struct dbus_watch_info* info = calloc(1, sizeof(struct dbus_watch_info));
if (info == NULL)
return;
info->conn = dbus_connection_ref(conn);
dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
watch_toggled, info, dbus_watch_info_free);
dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout,
timeout_toggled, NULL, NULL);
dbus_connection_set_dispatch_status_function(conn, dispatch_status,
NULL, NULL);
}
static gboolean setup_bus(DBusConnection* conn, const char* name,
DBusError* error)
{
gboolean result;
DBusDispatchStatus status;
if (name != NULL) {
result = dbus_request_name(conn, name, error);
if (error != NULL) {
if (dbus_error_is_set(error) == TRUE)
return FALSE;
}
if (result == FALSE)
return FALSE;
}
setup_dbus_with_main_loop(conn);
status = dbus_connection_get_dispatch_status(conn);
queue_dispatch(conn, status);
return TRUE;
}
DBusConnection* dbus_setup_bus(DBusBusType type, const char* name,
DBusError* error)
{
DBusConnection* conn;
conn = dbus_bus_get(type, error);
if (error != NULL) {
if (dbus_error_is_set(error) == TRUE)
return NULL;
}
if (conn == NULL)
return NULL;
if (setup_bus(conn, name, error) == FALSE) {
dbus_connection_unref(conn);
return NULL;
}
return conn;
}
DBusConnection* dbus_setup_private(DBusBusType type, const char* name,
DBusError* error)
{
DBusConnection* conn;
conn = dbus_bus_get_private(type, error);
if (error != NULL) {
if (dbus_error_is_set(error) == TRUE)
return NULL;
}
if (conn == NULL)
return NULL;
if (setup_bus(conn, name, error) == FALSE) {
dbus_connection_close(conn);
dbus_connection_unref(conn);
return NULL;
}
return conn;
}
gboolean dbus_request_name(DBusConnection* connection, const char* name,
DBusError* error)
{
int result;
result = dbus_bus_request_name(connection, name,
DBUS_NAME_FLAG_DO_NOT_QUEUE, error);
if (error != NULL) {
if (dbus_error_is_set(error) == TRUE)
return FALSE;
}
if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
if (error != NULL)
dbus_set_error(error, name, "Name already in use");
return FALSE;
}
return TRUE;
}
struct disconnect_data {
GDBusWatchFunction function;
void* user_data;
GDBusWatch* watcher;
};
static gboolean disconnected_signal(DBusConnection* conn,
DBusMessage* msg, void* data)
{
struct disconnect_data* dc_data = data;
info("Got disconnected from the system message bus");
dc_data->function(conn, dc_data->user_data);
dbus_connection_unref(conn);
dbus_watch_set_connection_state(dc_data->watcher, TRUE);
return FALSE;
}
gboolean dbus_client_add_disconnect_watch(GDBusClient* client,
GDBusWatchFunction function, void* user_data, DBusFreeFunction destroy)
{
struct disconnect_data* dc_data;
dbus_connection_set_exit_on_disconnect(client->dbus_conn, FALSE);
dc_data = calloc(1, sizeof(struct disconnect_data));
if (dc_data == NULL)
return FALSE;
dc_data->function = function;
dc_data->user_data = user_data;
dc_data->watcher = client->watcher;
if (dbus_add_signal_watch(client->watcher, NULL, NULL,
DBUS_INTERFACE_LOCAL, "Disconnected",
disconnected_signal, dc_data, free)
== 0) {
error("Failed to add watch for D-Bus Disconnected signal");
free(dc_data);
return FALSE;
}
dbus_connection_ref(client->dbus_conn);
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,226 +0,0 @@
/*
* Copyright (C) 2025 Xiaomi Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include "gdbus-internal.h"
#define POLICY_KIT_DBUS_NAME "org.freedesktop.PolicyKit1"
#define POLICY_KIT_INTERFACE "org.freedesktop.PolicyKit1.Authority"
#define POLICY_KIT_PATH "/org/freedesktop/PolicyKit1/Authority"
#define POLICY_KIT_ACTION "org.freedesktop.policykit.exec"
typedef enum polkit_interaction_flag {
POLKIT_FLAG_NONE = 0x00000000,
POLKIT_FLAG_ALLOW = 0x00000001
} polkit_interaction_flag;
typedef struct authorization_context {
void (*callback)(dbus_bool_t authorized, void* user_data);
void* user_data;
} authorization_context;
typedef struct dict_entry_builder {
DBusMessageIter iter;
const char* key;
const char* value;
} dict_entry_builder;
typedef enum contained_sig_type {
SIG_TYPE_EMPTY,
SIG_TYPE_VARIANT,
} contained_sig_type;
static const char* init_contained_signature_type(contained_sig_type type)
{
switch (type) {
case SIG_TYPE_EMPTY:
return DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
case SIG_TYPE_VARIANT:
return DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
default:
return NULL;
}
}
static void build_dict_entry(dict_entry_builder* builder)
{
DBusMessageIter dict, entry, variant;
dbus_message_iter_open_container(&builder->iter, DBUS_TYPE_ARRAY,
init_contained_signature_type(SIG_TYPE_VARIANT), &dict);
dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &builder->key);
dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
DBUS_TYPE_STRING_AS_STRING, &variant);
dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &builder->value);
dbus_message_iter_close_container(&entry, &variant);
dbus_message_iter_close_container(&dict, &entry);
dbus_message_iter_close_container(&builder->iter, &dict);
}
static void build_empty_dict(DBusMessageIter* iter)
{
DBusMessageIter dict;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
init_contained_signature_type(SIG_TYPE_EMPTY), &dict);
dbus_message_iter_close_container(iter, &dict);
}
static void build_authorization_arguments(DBusConnection* conn, DBusMessageIter* iter,
const char* action, polkit_interaction_flag flags)
{
const char* bus_name = dbus_bus_get_unique_name(conn);
const char* subject_kind = "system-bus-name";
const char* cancellation_id = "";
DBusMessageIter subject;
// build main subject
dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &subject);
dbus_message_iter_append_basic(&subject, DBUS_TYPE_STRING, &subject_kind);
dict_entry_builder builder = {
.iter = subject,
.key = "name",
.value = bus_name
};
build_dict_entry(&builder);
dbus_message_iter_close_container(iter, &subject);
// add less parameters
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
action ? action : POLICY_KIT_ACTION);
build_empty_dict(iter);
dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &flags);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &cancellation_id);
}
static dbus_bool_t parse_authorization_result(DBusMessageIter* iter)
{
DBusMessageIter recurse_iter;
dbus_bool_t auth = FALSE;
if (!iter)
return FALSE;
dbus_message_iter_recurse(iter, &recurse_iter);
dbus_message_iter_get_basic(&recurse_iter, &auth);
return auth;
}
static void handle_authorization_reply(DBusPendingCall* call, void* user_data)
{
authorization_context* context = user_data;
DBusMessage* reply = NULL;
DBusMessageIter iter;
dbus_bool_t authorized = FALSE;
if (!call || !context)
goto cleanup;
reply = dbus_pending_call_steal_reply(call);
if (!reply)
goto cleanup;
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
error("Authorization error: %s\n", dbus_message_get_error_name(reply));
goto cleanup;
}
if (!dbus_message_has_signature(reply, "(bba{ss})")) {
error("Invalid reply signature\n");
goto cleanup;
}
if (!dbus_message_iter_init(reply, &iter))
goto cleanup;
authorized = parse_authorization_result(&iter);
cleanup:
if (context != NULL && context->callback) {
context->callback(authorized, context->user_data);
}
if (reply)
dbus_message_unref(reply);
dbus_pending_call_unref(call);
}
int dbus_polkit_check_authorization(DBusConnection* conn,
const char* action, gboolean allow_interaction,
void (*callback)(dbus_bool_t, void*),
void* user_data, int timeout_ms)
{
DBusMessage* msg;
DBusMessageIter iter;
DBusPendingCall* pending_call = NULL;
polkit_interaction_flag flags;
if (!conn)
return -EINVAL;
authorization_context* context = calloc(1, sizeof(authorization_context));
if (!context)
return -ENOMEM;
msg = dbus_message_new_method_call(POLICY_KIT_DBUS_NAME, POLICY_KIT_PATH,
POLICY_KIT_INTERFACE, "CheckAuthorization");
if (!msg) {
free(context);
return -ENOMEM;
}
flags = allow_interaction ? POLKIT_FLAG_ALLOW : POLKIT_FLAG_NONE;
dbus_message_iter_init_append(msg, &iter);
build_authorization_arguments(conn, &iter, action, flags);
if (!dbus_connection_send_with_reply(conn, msg, &pending_call, timeout_ms)) {
dbus_message_unref(msg);
free(context);
return -EIO;
}
if (!pending_call) {
dbus_message_unref(msg);
free(context);
return -EIO;
}
context->callback = callback;
context->user_data = user_data;
dbus_pending_call_set_notify(pending_call, handle_authorization_reply,
context, free);
dbus_message_unref(msg);
return 0;
}

View File

@ -1,995 +0,0 @@
/*
* Copyright (C) 2025 Xiaomi Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <execinfo.h>
#include <stdio.h>
#include <string.h>
#include <dbus/dbus-list.h>
#include <dbus/dbus.h>
#include <uv.h>
#include "gdbus-internal.h"
static DBusHandlerResult message_filter(DBusConnection* connection,
DBusMessage* message, void* user_data);
struct GDBusWatch {
DBusConnection* conn;
guint serial;
DBusList* list;
gboolean conn_closed;
};
struct service_data {
DBusConnection* conn;
DBusPendingCall* call;
char* name;
const char* owner;
struct filter_callback* callback;
uv_idle_t handle;
};
struct filter_callback {
GDBusWatchFunction conn_func;
GDBusWatchFunction disc_func;
GDBusSignalFunction signal_func;
GDBusDestroyFunction destroy_func;
struct service_data* data;
void* user_data;
guint id;
};
struct filter_data {
DBusConnection* connection;
DBusHandleMessageFunction handle_func;
char* name;
char* owner;
char* path;
char* interface;
char* member;
char* argument;
DBusList* callbacks;
DBusList* processed;
guint name_watch;
gboolean lock;
gboolean registered;
GDBusWatch* watcher;
};
static int strcmp0(const char* str1, const char* str2)
{
if (str1 == NULL)
return -(str1 != str2);
if (str2 == NULL)
return -(str1 != str2);
return strcmp(str1, str2);
}
static char* strdup0(const char* str)
{
if (str)
return strdup(str);
return NULL;
}
static int get_watch_serial(GDBusWatch* watcher)
{
return ++watcher->serial;
}
static struct filter_data* filter_data_find_match(DBusConnection* connection,
DBusList* listener_list, const char* name, const char* owner,
const char* path, const char* interface, const char* member, const char* argument)
{
DBusList* current;
for (current = _dbus_list_get_first_link(&listener_list); current != NULL;
current = _dbus_list_get_next_link(&listener_list, current)) {
struct filter_data* data = current->data;
if (connection != data->connection)
continue;
if (strcmp0(name, data->name) != 0)
continue;
if (strcmp0(owner, data->owner) != 0)
continue;
if (strcmp0(path, data->path) != 0)
continue;
if (strcmp0(interface, data->interface) != 0)
continue;
if (strcmp0(member, data->member) != 0)
continue;
if (strcmp0(argument, data->argument) != 0)
continue;
return data;
}
return NULL;
}
static struct filter_data* filter_data_find(DBusConnection* connection, DBusList* listener_list)
{
DBusList* current;
for (current = _dbus_list_get_first_link(&listener_list); current != NULL;
current = _dbus_list_get_next_link(&listener_list, current)) {
struct filter_data* data = current->data;
if (connection != data->connection)
continue;
return data;
}
return NULL;
}
static void format_rule(struct filter_data* data, char* rule, size_t size)
{
const char* sender;
int offset;
offset = snprintf(rule, size, "type='signal'");
sender = data->name ?: data->owner;
if (sender)
offset += snprintf(rule + offset, size - offset,
",sender='%s'", sender);
if (data->path)
offset += snprintf(rule + offset, size - offset,
",path='%s'", data->path);
if (data->interface)
offset += snprintf(rule + offset, size - offset,
",interface='%s'", data->interface);
if (data->member)
offset += snprintf(rule + offset, size - offset,
",member='%s'", data->member);
if (data->argument)
snprintf(rule + offset, size - offset,
",arg0='%s'", data->argument);
}
static gboolean add_match(struct filter_data* data,
DBusHandleMessageFunction filter)
{
DBusError err;
char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
format_rule(data, rule, sizeof(rule));
dbus_error_init(&err);
dbus_bus_add_match(data->connection, rule, &err);
if (dbus_error_is_set(&err)) {
error("Adding match rule \"%s\" failed: %s", rule,
err.message);
dbus_error_free(&err);
return FALSE;
}
data->handle_func = filter;
data->registered = TRUE;
return TRUE;
}
static gboolean remove_match(struct filter_data* data)
{
DBusError err;
char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
if (data->watcher->conn_closed) {
/* If the connection is disconnected, we don't need to remove the match */
return TRUE;
}
format_rule(data, rule, sizeof(rule));
dbus_error_init(&err);
dbus_bus_remove_match(data->connection, rule, &err);
if (dbus_error_is_set(&err)) {
error("GDBUS Removing owner match rule for %s failed: %s",
rule, err.message);
dump_stack();
dbus_error_free(&err);
return FALSE;
}
return TRUE;
}
static void filter_data_free(struct filter_data* data, DBusList* listener_list)
{
DBusList* l;
/* Remove filter if there are no listeners left for the connection */
if (filter_data_find(data->connection, listener_list) == NULL) {
dbus_connection_remove_filter(data->connection, message_filter,
data->watcher);
}
for (l = _dbus_list_get_first_link(&data->callbacks); l != NULL;
l = _dbus_list_get_next_link(&data->callbacks, l))
free(l->data);
_dbus_list_clear(&data->callbacks);
dbus_remove_watch(data->watcher, data->name_watch);
free(data->name);
free(data->owner);
free(data->path);
free(data->interface);
free(data->member);
free(data->argument);
/* no listeners left for the connection */
if (_dbus_list_get_last(&listener_list) == NULL) {
free_dbus_watch(data->watcher);
}
dbus_connection_unref(data->connection);
free(data);
}
static struct filter_data* filter_data_get(GDBusWatch* watcher,
DBusHandleMessageFunction filter,
const char* sender, const char* path, const char* interface,
const char* member, const char* argument)
{
struct filter_data* data;
const char *name = NULL, *owner = NULL;
if (filter_data_find(watcher->conn, watcher->list) == NULL) {
if (!dbus_connection_add_filter(watcher->conn,
message_filter, watcher, NULL)) {
error("dbus_connection_add_filter() failed");
return NULL;
}
}
if (sender != NULL) {
if (sender[0] == ':')
owner = sender;
else
name = sender;
}
data = filter_data_find_match(watcher->conn, watcher->list, name, owner, path,
interface, member, argument);
if (data)
return data;
data = calloc(1, sizeof(struct filter_data));
data->connection = dbus_connection_ref(watcher->conn);
data->name = strdup0(name);
data->owner = strdup0(owner);
data->path = strdup0(path);
data->interface = strdup0(interface);
data->member = strdup0(member);
data->argument = strdup0(argument);
data->watcher = watcher;
if (!add_match(data, filter)) {
dbus_connection_unref(data->connection);
free(data->name);
free(data->owner);
free(data->path);
free(data->interface);
free(data->member);
free(data->argument);
free(data);
return NULL;
}
_dbus_list_append(&watcher->list, data);
return data;
}
static struct filter_callback* filter_data_find_callback(
struct filter_data* data,
guint id)
{
DBusList* l;
for (l = _dbus_list_get_first_link(&data->callbacks); l != NULL;
l = _dbus_list_get_next_link(&data->callbacks, l)) {
struct filter_callback* cb = l->data;
if (cb->id == id)
return cb;
}
for (l = _dbus_list_get_first_link(&data->processed); l != NULL;
l = _dbus_list_get_next_link(&data->processed, l)) {
struct filter_callback* cb = l->data;
if (cb->id == id)
return cb;
}
return NULL;
}
static void filter_data_call_and_free(struct filter_data* data, DBusList* listener_list)
{
DBusList* l;
for (l = _dbus_list_get_first_link(&data->callbacks); l != NULL;
l = _dbus_list_get_next_link(&data->callbacks, l)) {
struct filter_callback* cb = l->data;
if (cb->disc_func)
cb->disc_func(data->connection, cb->user_data);
if (cb->destroy_func)
cb->destroy_func(cb->user_data);
}
filter_data_free(data, listener_list);
}
static struct filter_callback* filter_data_add_callback(
struct filter_data* data,
GDBusWatchFunction connect,
GDBusWatchFunction disconnect,
GDBusSignalFunction signal,
GDBusDestroyFunction destroy,
guint watch_id,
void* user_data)
{
struct filter_callback* cb = NULL;
cb = calloc(1, sizeof(struct filter_callback));
cb->conn_func = connect;
cb->disc_func = disconnect;
cb->signal_func = signal;
cb->destroy_func = destroy;
cb->user_data = user_data;
cb->id = watch_id;
if (data->lock)
_dbus_list_append(&data->processed, cb);
else
_dbus_list_append(&data->callbacks, cb);
return cb;
}
static void close_cb(uv_handle_t* handle)
{
free(handle->data);
}
static void service_data_free(struct service_data* data)
{
struct filter_callback* callback = data->callback;
dbus_connection_unref(data->conn);
if (data->call)
dbus_pending_call_unref(data->call);
free(data->name);
callback->data = NULL;
uv_close((uv_handle_t*)&data->handle, close_cb);
}
/* Returns TRUE if data is freed */
static gboolean filter_data_remove_callback(struct filter_data* data,
struct filter_callback* cb)
{
_dbus_list_remove(&data->callbacks, cb);
_dbus_list_remove(&data->processed, cb);
/* Cancel pending operations */
if (cb->data) {
if (cb->data->call)
dbus_pending_call_cancel(cb->data->call);
service_data_free(cb->data);
}
if (cb->destroy_func)
cb->destroy_func(cb->user_data);
free(cb);
/* Don't remove the filter if other callbacks exist or data is lock
* processing callbacks */
if (data->callbacks || data->lock)
return FALSE;
if (data->registered && !remove_match(data))
return FALSE;
_dbus_list_remove(&data->watcher->list, data);
filter_data_free(data, data->watcher->list);
return TRUE;
}
static DBusHandlerResult signal_filter(DBusConnection* connection,
DBusMessage* message, void* user_data)
{
struct filter_data* data = user_data;
struct filter_callback* cb;
while (data->callbacks) {
cb = data->callbacks->data;
if (cb->signal_func && !cb->signal_func(connection, message, cb->user_data)) {
if (filter_data_remove_callback(data, cb))
break;
continue;
}
/* Check if the watch was removed/freed by the callback
* function */
if (_dbus_list_find_last(&data->callbacks, cb) == NULL)
continue;
_dbus_list_remove(&data->callbacks, cb);
_dbus_list_append(&data->processed, cb);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void update_name_cache(DBusList* listener_list, const char* name, const char* owner)
{
DBusList* l;
for (l = _dbus_list_get_first_link(&listener_list); l != NULL;
l = _dbus_list_get_next_link(&listener_list, l)) {
struct filter_data* data = l->data;
if (strcmp0(data->name, name) != 0)
continue;
free(data->owner);
data->owner = strdup0(owner);
}
}
static const char* check_name_cache(DBusList* listener_list, const char* name)
{
DBusList* l;
for (l = _dbus_list_get_first_link(&listener_list); l != NULL;
l = _dbus_list_get_next_link(&listener_list, l)) {
struct filter_data* data = l->data;
if (strcmp0(data->name, name) != 0)
continue;
return data->owner;
}
return NULL;
}
static DBusHandlerResult service_filter(DBusConnection* connection,
DBusMessage* message, void* user_data)
{
struct filter_data* data = user_data;
struct filter_callback* cb;
char *name, *old, *new;
if (!dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &old,
DBUS_TYPE_STRING, &new,
DBUS_TYPE_INVALID)) {
error("Invalid arguments for NameOwnerChanged signal");
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
update_name_cache(data->watcher->list, name, new);
while (data->callbacks) {
cb = data->callbacks->data;
if (*new == '\0') {
if (cb->disc_func)
cb->disc_func(connection, cb->user_data);
} else {
if (cb->conn_func)
cb->conn_func(connection, cb->user_data);
}
/* Check if the watch was removed/freed by the callback
* function */
if (_dbus_list_find_last(&data->callbacks, cb) == NULL)
continue;
/* Only auto remove if it is a bus name watch */
if (data->argument[0] == ':' && (cb->conn_func == NULL || cb->disc_func == NULL)) {
if (filter_data_remove_callback(data, cb))
break;
continue;
}
_dbus_list_remove(&data->callbacks, cb);
_dbus_list_append(&data->processed, cb);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static bool process_signal_message(DBusMessage* message,
const char** sender, const char** path,
const char** iface, const char** member,
const char** arg)
{
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
return false;
*sender = dbus_message_get_sender(message);
*path = dbus_message_get_path(message);
*iface = dbus_message_get_interface(message);
*member = dbus_message_get_member(message);
if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, arg, DBUS_TYPE_INVALID))
*arg = NULL;
return true;
}
static int filter_data_match(const char* str1, const char* data_param)
{
if (data_param == NULL)
return 0;
if (str1 == NULL)
return -1;
return strcmp(str1, data_param);
}
static gboolean match_listener_data(struct filter_data* data, DBusConnection* connection,
const char* sender, const char* path,
const char* iface, const char* member, const char* arg)
{
if (connection != data->connection)
return FALSE;
if (filter_data_match(sender, data->owner) != 0)
return FALSE;
if (filter_data_match(path, data->path) != 0)
return FALSE;
if (filter_data_match(iface, data->interface) != 0)
return FALSE;
if (filter_data_match(member, data->member) != 0)
return FALSE;
if (filter_data_match(arg, data->argument) != 0)
return FALSE;
return TRUE;
}
static void process_listener_callbacks(struct filter_data* data, DBusConnection* connection,
DBusMessage* message)
{
if (!data->handle_func)
return;
data->lock = TRUE;
data->handle_func(connection, message, data);
data->callbacks = data->processed;
data->processed = NULL;
data->lock = FALSE;
}
static void process_listeners(DBusList* listener_list, DBusConnection* connection,
DBusMessage* message, DBusList** delete_listener, const char* sender,
const char* path, const char* iface, const char* member, const char* arg)
{
DBusList* current;
struct filter_data* data;
for (current = _dbus_list_get_first_link(&listener_list); current;
current = _dbus_list_get_next_link(&listener_list, current)) {
data = current->data;
if (!match_listener_data(data, connection, sender,
path, iface, member, arg))
continue;
process_listener_callbacks(data, connection, message);
if (!data->callbacks)
_dbus_list_prepend(delete_listener, current);
}
}
static void cleanup_listeners(DBusList* delete_listener, GDBusWatch* watcher)
{
DBusList* current;
struct filter_data* data;
for (current = _dbus_list_get_first_link(&delete_listener); current;
current = _dbus_list_get_next_link(&delete_listener, current)) {
DBusList* l = current->data;
data = l->data;
/* Has any other callback added callbacks back to this data? */
if (data->callbacks)
continue;
remove_match(data);
_dbus_list_remove_link(&watcher->list, l);
filter_data_free(data, watcher->list);
}
_dbus_list_clear(&delete_listener);
}
static DBusHandlerResult message_filter(DBusConnection* connection,
DBusMessage* message, void* user_data)
{
const char *sender, *path, *iface, *member, *arg = NULL;
DBusList* delete_listener = NULL;
GDBusWatch* watcher = user_data;
if (!process_signal_message(message, &sender, &path,
&iface, &member, &arg))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
process_listeners(watcher->list, connection, message, &delete_listener,
sender, path, iface, member, arg);
if (delete_listener)
cleanup_listeners(delete_listener, watcher);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void update_service(uv_idle_t* handle)
{
struct service_data* data = handle->data;
struct filter_callback* cb = data->callback;
DBusConnection* conn;
conn = dbus_connection_ref(data->conn);
service_data_free(data);
if (cb->conn_func)
cb->conn_func(conn, cb->user_data);
dbus_connection_unref(conn);
}
static void service_reply(DBusPendingCall* call, void* user_data)
{
struct service_data* data = user_data;
DBusMessage* reply;
DBusError err;
reply = dbus_pending_call_steal_reply(call);
if (reply == NULL)
return;
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, reply))
goto fail;
if (dbus_message_get_args(reply, &err, DBUS_TYPE_STRING,
&data->owner, DBUS_TYPE_INVALID)
== FALSE)
goto fail;
update_service(&data->handle);
goto done;
fail:
error("service_reply fail: %s", err.message);
dbus_error_free(&err);
service_data_free(data);
done:
dbus_message_unref(reply);
}
static struct service_data* create_service_data(DBusConnection* conn,
const char* name,
struct filter_callback* cb)
{
struct service_data* data = calloc(1, sizeof(*data));
if (!data) {
error("%s: malloc failed", __func__);
return NULL;
}
data->conn = dbus_connection_ref(conn);
data->name = strdup0(name);
data->callback = cb;
cb->data = data;
return data;
}
static bool init_uv_handle(struct service_data* data)
{
if (uv_idle_init(uv_default_loop(), &data->handle) != 0) {
error("%s: uv_idle_init failed", __func__);
return false;
}
data->handle.data = data;
return true;
}
static gboolean send_name_owner_request(struct service_data* data, const char* name)
{
DBusMessage* msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner");
if (!msg) {
error("%s: dbus_message_new_method_call failed", __func__);
return FALSE;
}
dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
if (!dbus_connection_send_with_reply(data->conn, msg, &data->call, -1)) {
error("%s: dbus_connection_send_with_reply failed", __func__);
dbus_message_unref(msg);
return FALSE;
}
if (!data->call) {
error("%s: dbus reply failed with empty pendingcall", __func__);
dbus_message_unref(msg);
return FALSE;
}
if (dbus_pending_call_get_completed(data->call)) {
service_reply(data->call, data);
} else {
dbus_pending_call_set_notify(data->call, service_reply, data, NULL);
}
dbus_message_unref(msg);
return TRUE;
}
static void check_service(DBusConnection* conn, const char* name,
struct filter_callback* cb, DBusList* listener_list)
{
struct service_data* data = create_service_data(conn, name, cb);
if (!data)
return;
if (!init_uv_handle(data)) {
dbus_connection_unref(data->conn);
free(data->name);
free(data);
return;
}
data->owner = check_name_cache(listener_list, name);
if (data->owner) {
if (uv_idle_start(&data->handle, update_service) != 0) {
error("%s: uv_idle_start failed:", __func__);
uv_close((uv_handle_t*)&data->handle, NULL);
dbus_connection_unref(data->conn);
free(data->name);
free(data);
}
return;
}
if (send_name_owner_request(data, name) == FALSE) {
uv_close((uv_handle_t*)&data->handle, NULL);
dbus_connection_unref(data->conn);
free(data->name);
free(data);
return;
}
}
guint dbus_add_service_watch(GDBusWatch* watcher, const char* name,
GDBusWatchFunction connect,
GDBusWatchFunction disconnect,
void* user_data, GDBusDestroyFunction destroy)
{
struct filter_data* data;
struct filter_callback* cb;
if (name == NULL)
return 0;
data = filter_data_get(watcher, service_filter, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS, "NameOwnerChanged", name);
if (data == NULL)
return 0;
cb = filter_data_add_callback(data, connect, disconnect, NULL, destroy,
get_watch_serial(watcher), user_data);
if (cb == NULL)
return 0;
if (connect)
check_service(watcher->conn, name, cb, watcher->list);
return cb->id;
}
guint dbus_add_service_disconnect_watch(GDBusWatch* watcher, const char* name,
GDBusWatchFunction func, void* user_data, GDBusDestroyFunction destroy)
{
return dbus_add_service_watch(watcher, name, NULL, func, user_data, destroy);
}
guint dbus_add_signal_watch(GDBusWatch* watcher,
const char* sender, const char* path,
const char* interface, const char* member,
GDBusSignalFunction function, void* user_data,
GDBusDestroyFunction destroy)
{
struct filter_data* data;
struct filter_callback* cb;
data = filter_data_get(watcher, signal_filter, sender, path,
interface, member, NULL);
if (data == NULL)
return 0;
cb = filter_data_add_callback(data, NULL, NULL, function, destroy,
get_watch_serial(watcher), user_data);
if (cb == NULL)
return 0;
if (data->name != NULL && data->name_watch == 0)
data->name_watch = dbus_add_service_watch(watcher,
data->name, NULL,
NULL, NULL, NULL);
return cb->id;
}
guint dbus_add_properties_watch(GDBusWatch* watcher,
const char* sender, const char* path,
const char* interface,
GDBusSignalFunction function, void* user_data,
GDBusDestroyFunction destroy)
{
struct filter_data* data;
struct filter_callback* cb;
data = filter_data_get(watcher, signal_filter, sender, path,
DBUS_INTERFACE_PROPERTIES, "PropertiesChanged", interface);
if (data == NULL)
return 0;
cb = filter_data_add_callback(data, NULL, NULL, function, destroy,
get_watch_serial(watcher), user_data);
if (cb == NULL)
return 0;
if (data->name != NULL && data->name_watch == 0)
data->name_watch = dbus_add_service_watch(watcher,
data->name, NULL,
NULL, NULL, NULL);
return cb->id;
}
gboolean dbus_remove_watch(GDBusWatch* watcher, guint id)
{
struct filter_data* data;
struct filter_callback* cb;
DBusList* ldata;
if (id == 0)
return FALSE;
for (ldata = _dbus_list_get_first_link(&watcher->list); ldata != NULL;
ldata = _dbus_list_get_next_link(&watcher->list, ldata)) {
data = ldata->data;
cb = filter_data_find_callback(data, id);
if (cb) {
filter_data_remove_callback(data, cb);
return TRUE;
}
}
return FALSE;
}
void dbus_remove_all_watches(GDBusWatch* watcher)
{
struct filter_data* data;
while ((data = filter_data_find(watcher->conn, watcher->list))) {
_dbus_list_remove(&watcher->list, data);
filter_data_call_and_free(data, watcher->list);
}
}
GDBusWatch* new_dbus_watch(DBusConnection* connection)
{
GDBusWatch* watcher;
watcher = calloc(1, sizeof(GDBusWatch));
if (watcher == NULL)
return NULL;
watcher->conn = dbus_connection_ref(connection);
watcher->list = NULL;
watcher->serial = 0;
watcher->conn_closed = FALSE;
return watcher;
}
void free_dbus_watch(GDBusWatch* watcher)
{
dbus_connection_unref(watcher->conn);
free(watcher);
}
guint dbus_client_add_service_watch(GDBusClient* client, const char* name,
GDBusWatchFunction connect, GDBusWatchFunction disconnect,
void* user_data, GDBusDestroyFunction destroy)
{
return dbus_add_service_watch(client->watcher, name, connect, disconnect,
user_data, destroy);
}
guint dbus_client_add_service_disconnect_watch(GDBusClient* client, const char* name,
GDBusWatchFunction function, void* user_data, GDBusDestroyFunction destroy)
{
return dbus_add_service_disconnect_watch(client->watcher, name, function, user_data, destroy);
}
guint dbus_client_add_signal_watch(GDBusClient* client, const char* sender,
const char* path, const char* interface, const char* member,
GDBusSignalFunction function, void* user_data, GDBusDestroyFunction destroy)
{
return dbus_add_signal_watch(client->watcher, sender, path, interface,
member, function, user_data, destroy);
}
guint dbus_client_add_properties_watch(GDBusClient* client,
const char* sender, const char* path, const char* interface,
GDBusSignalFunction function, void* user_data, GDBusDestroyFunction destroy)
{
return dbus_add_properties_watch(client->watcher, sender, path, interface,
function, user_data, destroy);
}
gboolean dbus_client_remove_watch(GDBusClient* client, guint tag)
{
return dbus_remove_watch(client->watcher, tag);
}
void dbus_client_remove_all_watches(GDBusClient* client)
{
dbus_remove_all_watches(client->watcher);
}
void dbus_watch_set_connection_state(GDBusWatch* watcher, gboolean closed)
{
watcher->conn_closed = closed;
}

View File

@ -67,77 +67,13 @@ static ssize_t recv_safe(int sockfd, char* buf, size_t offset, size_t len)
}
/****************************************************************************
* Name: property_connect_one
* Name: property_connect
*
* Description:
* Initialize client socket and connect to server
*
* Input Parameters:
* addr - server address
* addrlen - server address length
*
* Returned Value:
* On success return client socket fd.
* On error return error value (<0).
*
****************************************************************************/
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_RPMSG)
static int property_connect_one(const struct sockaddr* addr,
socklen_t addrlen)
{
int fd = socket(addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return -errno;
int ret = connect(fd, addr, addrlen);
if (ret < 0) {
ret = -errno;
close(fd);
return ret;
}
return fd;
}
#endif
#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_RPMSG)
/****************************************************************************
* Name: use_local_socket
*
* Description:
* Determine whether to use local socket or rpmsg socket to
* connect to server
*
* Returned Value:
* true: use local socket
* false: use rpmsg socket
*
****************************************************************************/
static inline bool use_local_socket(void)
{
#ifdef CONFIG_KVDB_SERVER_CPUNAME
struct sockaddr_rpmsg addr;
socklen_t addrlen = sizeof(addr);
int fd = socket(AF_RPMSG, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd >= 0) {
int ret = getsockname(fd, (struct sockaddr*)&addr, &addrlen);
close(fd);
if (ret == 0) {
return strcmp(addr.rp_cpu, CONFIG_KVDB_SERVER_CPUNAME) == 0;
}
}
#endif
return true;
}
#endif
/****************************************************************************
* Name: property_connect
*
* Description:
* Initialize client socket and connect to server
* None
*
* Returned Value:
* On success return client socket fd.
@ -147,45 +83,48 @@ static inline bool use_local_socket(void)
static int property_connect(void)
{
#ifdef CONFIG_NET_LOCAL
const struct sockaddr_un laddr = {
#ifdef CONFIG_KVDB_SERVER
int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
#else
int fd = socket(AF_RPMSG, SOCK_STREAM | SOCK_CLOEXEC, 0);
#endif
if (fd < 0)
return -errno;
#if CONFIG_KVDB_TIMEOUT_INTERVAL
struct timeval timeout = {
.tv_sec = CONFIG_KVDB_TIMEOUT_INTERVAL,
.tv_usec = 0,
};
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#endif
#ifdef CONFIG_KVDB_SERVER
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = PROP_SERVER_PATH,
};
#endif
#ifdef CONFIG_NET_RPMSG
const struct sockaddr_rpmsg raddr = {
#else
struct sockaddr_rpmsg addr = {
.rp_family = AF_RPMSG,
.rp_name = PROP_SERVER_PATH,
.rp_cpu = CONFIG_KVDB_SERVER_CPUNAME,
};
#endif
int ret = -ENOTSUP;
#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_RPMSG)
bool use_local = use_local_socket();
#endif
while (1) {
#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_RPMSG)
if (use_local)
ret = property_connect_one((const struct sockaddr*)&laddr, sizeof(laddr));
else
ret = property_connect_one((const struct sockaddr*)&raddr, sizeof(raddr));
#elif defined(CONFIG_NET_LOCAL)
ret = property_connect_one((const struct sockaddr*)&laddr, sizeof(laddr));
#elif defined(CONFIG_NET_RPMSG)
ret = property_connect_one((const struct sockaddr*)&raddr, sizeof(raddr));
#else
break;
#endif
if (ret >= 0)
break;
int ret = connect(fd, (const struct sockaddr*)&addr, sizeof(addr));
if (ret < 0 && errno != ENOENT) {
ret = -errno;
close(fd);
return ret;
} else if (ret == 0) {
return fd;
}
usleep(1000);
}
return ret;
}
/****************************************************************************

View File

@ -68,7 +68,6 @@ static int kvdb_monitor_open(kvdb_server* server, int fd, const char* key,
/* Malloc monitor element to store [key, fd] pair */
kvdb_monitor* mon = zalloc(sizeof(kvdb_monitor) + key_len);
if (mon == NULL) {
KVERR("kvdb_monitor_open: zalloc failed\n");
return -ENOMEM;
}
@ -79,7 +78,6 @@ static int kvdb_monitor_open(kvdb_server* server, int fd, const char* key,
};
int ret = epoll_ctl(server->efd, EPOLL_CTL_ADD, fd, &ev);
if (ret < 0) {
KVERR("kvdb_monitor_open: epoll_ctl failed, ret=%d, errno=%d\n", ret, errno);
free(mon);
return ret;
}
@ -291,22 +289,16 @@ static int kvdb_bind(int fd[])
for (int i = 0; i < KVFD_COUNT; i++) {
fd[i] = socket(family[i], SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd[i] < 0) {
KVERR("kvdb_bind: socket failed, i=%d, errno=%d\n", i, errno);
if (fd[i] < 0)
continue;
}
int ret = bind(fd[i], addr[i], addrlen[i]);
if (ret < 0) {
KVERR("kvdb_bind: bind failed, i=%d, ret=%d, errno=%d\n", i, ret, errno);
if (ret < 0)
return ret;
}
ret = listen(fd[i], CONFIG_KVDB_BACKLOG_CONNS);
if (ret < 0) {
KVERR("kvdb_bind: listen failed, i=%d, ret=%d, errno=%d\n", i, ret, errno);
if (ret < 0)
return ret;
}
}
return 0;
@ -346,14 +338,10 @@ static ssize_t kvdb_recv(int sockfd, char* buf, size_t offset, size_t len)
{
while (offset < len) {
ssize_t ret = recv(sockfd, buf + offset, len - offset, 0);
if (ret < 0) {
KVERR("kvdb_recv: recv failed, ret=%zd, errno=%d\n", ret, errno);
if (ret < 0)
return ret;
}
if (ret == 0) {
KVERR("kvdb_recv: recv returned 0, connection closed\n");
if (ret == 0)
return -ENODATA;
}
offset += ret;
}
@ -366,30 +354,26 @@ static bool kvdb_client(kvdb_server* server, int fd)
ssize_t len;
char* msg;
#if defined(CONFIG_KVDB_TIMEOUT_INTERVAL) && CONFIG_KVDB_TIMEOUT_INTERVAL > 0
#if CONFIG_KVDB_TIMEOUT_INTERVAL
struct timeval timeout = {
.tv_sec = 0,
.tv_usec = CONFIG_KVDB_TIMEOUT_INTERVAL,
.tv_sec = CONFIG_KVDB_TIMEOUT_INTERVAL,
.tv_usec = 0,
};
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0
|| setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
KVWARN("Failed to set socket timeout\n");
}
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#endif
msg = malloc(PROP_MSG_MAX);
if (msg == NULL) {
KVERR("kvdb_client: malloc failed\n");
KVERR("malloc failed\n");
goto out;
}
msg[0] = msg[1] = msg[2] = 0; /* zero the first key bytes */
len = recv(fd, msg, PROP_MSG_MAX, 0);
if (len <= 0) {
KVERR("kvdb_client: recv failed, len=%zd, errno=%d\n", len, errno);
if (len <= 0)
goto out;
}
switch (msg[0]) {
case 'D': {
@ -522,7 +506,6 @@ static bool kvdb_client(kvdb_server* server, int fd)
}
case 'E': {
int ret = 0;
KVERR("kvdb_client: received exit command, stopping server\n");
server->running = false;
kvdb_uninit(server->kvdb);
send(fd, &ret, sizeof(ret), 0);
@ -542,17 +525,14 @@ static void kvdb_loop(kvdb_server* server)
struct timespec ts;
server->efd = epoll_create(KVFD_MAX);
if (server->efd < 0) {
KVERR("kvdb_loop: epoll_create failed, errno=%d\n", errno);
if (server->efd < 0)
return;
}
for (int i = 0; i < KVFD_COUNT; i++) {
if (server->fd[i] >= 0) {
evs[0].data.ptr = &server->fd[i];
evs[0].events = EPOLLIN;
if (epoll_ctl(server->efd, EPOLL_CTL_ADD, server->fd[i], &evs[0]) < 0) {
KVERR("kvdb_loop: epoll_ctl ADD failed, fd=%d, errno=%d\n", server->fd[i], errno);
close(server->efd);
return;
}
@ -606,7 +586,6 @@ static void kvdb_loop(kvdb_server* server)
}
}
}
KVERR("kvdb_loop: server loop exited, running=%d\n", server->running);
}
/****************************************************************************
@ -630,21 +609,16 @@ int main(int argc, char* argv[])
.head = LIST_HEAD_INITIALIZER(),
};
int ret = kvdb_bind(server.fd);
if (ret < 0) {
KVERR("main: kvdb_bind failed, ret=%d, errno=%d\n", ret, errno);
if (ret < 0)
goto out;
}
ret = kvdb_init(&server.kvdb);
if (ret < 0) {
KVERR("main: kvdb_init failed, ret=%d\n", ret);
if (ret < 0)
goto out;
}
kvdb_load(server.kvdb, CONFIG_KVDB_SOURCE_PATH, false);
kvdb_loop(&server);
out:
KVERR("main: exiting, ret=%d\n", ret);
kvdb_unbind(server.fd);
return -ret;
}

View File

@ -55,58 +55,58 @@ void atrace_set_tracing_enabled(bool enabled)
void atrace_begin_body(const char* name)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "B|%d|%s", gettid(), name);
sched_note_printf(NOTE_TAG_ALWAYS, "B|%d|%s", gettid(), name);
}
void atrace_end_body(void)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "E|%d", gettid());
sched_note_printf(NOTE_TAG_ALWAYS, "E|%d", gettid());
}
void atrace_async_begin_body(const char* name, int32_t cookie)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "S|%d|%s|%" PRId32, gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "S|%d|%s|%" PRId32, gettid(),
name, cookie);
}
void atrace_async_end_body(const char* name, int32_t cookie)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "F|%d|%s|%" PRId32, gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "F|%d|%s|%" PRId32, gettid(),
name, cookie);
}
void atrace_async_for_track_begin_body(const char* track_name,
const char* name, int32_t cookie)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "G|%d|%s|%s|%" PRId32, gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "G|%d|%s|%s|%" PRId32, gettid(),
track_name, name, cookie);
}
void atrace_async_for_track_end_body(const char* track_name, const char* name, int32_t cookie)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "H|%d|%s|%s|%" PRId32, gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "H|%d|%s|%s|%" PRId32, gettid(),
track_name, name, cookie);
}
void atrace_instant_body(const char* name)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "I|%d|%s", gettid(), name);
sched_note_printf(NOTE_TAG_ALWAYS, "I|%d|%s", gettid(), name);
}
void atrace_instant_for_track_body(const char* track_name, const char* name)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "N|%d|%s|%s", gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "N|%d|%s|%s", gettid(),
track_name, name);
}
void atrace_int_body(const char* name, int32_t value)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "C|%d|%s|%" PRId32,
sched_note_printf(NOTE_TAG_ALWAYS, "C|%d|%s|%" PRId32,
gettid(), name, value);
}
void atrace_int64_body(const char* name, int64_t value)
{
sched_note_printf(NOTE_TAG_ALWAYS, LOG_INFO, "C|%d|%s|%" PRId64, gettid(),
sched_note_printf(NOTE_TAG_ALWAYS, "C|%d|%s|%" PRId64, gettid(),
name, value);
}