diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e0df852f..cadb7208 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest steps: - name: install system dependencies - run: sudo apt-get update && sudo apt-get install libdbus-1-dev libusb-1.0-0-dev + run: sudo apt-get update && sudo apt-get install libdbus-1-dev libudev-dev libusb-1.0-0-dev - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest steps: - name: install system dependencies - run: sudo apt-get update && sudo apt-get install libdbus-1-dev libusb-1.0-0-dev + run: sudo apt-get update && sudo apt-get install libdbus-1-dev libudev-dev libusb-1.0-0-dev - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: diff --git a/.gitignore b/.gitignore index 642714af..78dc5004 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,17 @@ /.cargo/ -/debian/files +debian/* +!debian/*.install +!debian/*.postinst +!debian/*.postrm +!debian/*.preinst +!debian/*.service +!debian/*.triggers +!debian/changelog +!debian/control +!debian/copyright +!debian/postinst +!debian/rules +!debian/source /target/ /vendor/ -vendor.tar.xz +vendor.* diff --git a/.vscode/settings.json b/.vscode/settings.json index 9fea980f..e623b506 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "rust-analyzer.checkOnSave.command": "clippy" -} + "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.checkOnSave.extraArgs": ["--", "-W", "clippy::pedantic"], +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 254a6a28..0157ef5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,14 +3,95 @@ version = 3 [[package]] -name = "atty" -version = "0.2.14" +name = "aho-corasick" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ - "hermit-abi", + "memchr", +] + +[[package]] +name = "async-broadcast" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b19760fa2b7301cf235360ffd6d3558b1ed4249edd16d6cca8d690cee265b95" +dependencies = [ + "event-listener", + "futures-core", + "parking_lot", +] + +[[package]] +name = "async-executor" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +dependencies = [ + "async-lock", + "autocfg", + "concurrent-queue", + "futures-lite", "libc", - "winapi", + "log", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "windows-sys", +] + +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + +[[package]] +name = "async-recursion" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" + +[[package]] +name = "async-trait" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -25,11 +106,26 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "cc" -version = "1.0.74" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -39,14 +135,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.0.19" +version = "4.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e67816e006b17427c9b4386915109b494fec2d929c63e3bd3561234cbf1bf1e" +checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" dependencies = [ - "atty", "bitflags", "clap_derive", "clap_lex", + "is-terminal", "once_cell", "strsim 0.10.0", "termcolor", @@ -54,9 +150,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.0.18" +version = "4.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck", "proc-macro-error", @@ -80,6 +176,43 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5b80dba65d26e0c4b692ad0312b837f1177e8175031af57fd1de4f3bc36b430" +[[package]] +name = "concurrent-queue" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "darling" version = "0.10.2" @@ -117,9 +250,9 @@ dependencies = [ [[package]] name = "dbus" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" dependencies = [ "futures-channel", "futures-util", @@ -130,9 +263,9 @@ dependencies = [ [[package]] name = "dbus-crossroads" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554114296d012b33fdaf362a733db6dc5f73c4c9348b8b620ddd42e61b406e30" +checksum = "3a4c83437187544ba5142427746835061b330446ca8902eabd70e4afb8f76de0" dependencies = [ "dbus", ] @@ -148,6 +281,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_setters" version = "0.1.5" @@ -160,6 +304,93 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "enumflags2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + [[package]] name = "fern" version = "0.6.1" @@ -223,6 +454,21 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.25" @@ -264,6 +510,27 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.4.0" @@ -272,22 +539,29 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hidapi" -version = "1.4.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d26e1151deaab68f34fbfd16d491a2a0170cf98d69d3efa23873b567a4199e1" +checksum = "41cd9e1a4d30b483574da670f07701c87469a4919062b4236f0147a7df805cab" dependencies = [ "cc", "libc", "pkg-config", + "winapi", ] [[package]] @@ -318,6 +592,15 @@ dependencies = [ "libc", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "intel-pstate" version = "1.0.1" @@ -330,26 +613,64 @@ dependencies = [ ] [[package]] -name = "itoa" +name = "io-lifetimes" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libdbus-sys" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b" +checksum = "2264f9d90a9b4e60a2dc722ad899ea0374f03c2e96e755fe22a8f551d4d5fb3c" dependencies = [ "pkg-config", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.17" @@ -365,6 +686,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "mio" version = "0.8.5" @@ -377,6 +707,20 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + [[package]] name = "numtoa" version = "0.2.4" @@ -385,15 +729,54 @@ checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "ordered-stream" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "d4eb9ba3f3e42dbdd3b7b122de5ca169c81e93d561eb900da3a8c99bcfcf381a" +dependencies = [ + "futures-core", + "pin-project-lite", +] [[package]] name = "os_str_bytes" -version = "6.3.1" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] [[package]] name = "pin-project-lite" @@ -413,6 +796,37 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "polling" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "log", + "wepoll-ffi", + "windows-sys", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -439,42 +853,138 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rustix" +version = "0.36.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "scopeguard" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -483,15 +993,37 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -510,6 +1042,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "smart-default" version = "0.6.0" @@ -531,6 +1069,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.9.3" @@ -545,9 +1089,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -564,15 +1108,17 @@ dependencies = [ [[package]] name = "system76-power" -version = "1.1.24" +version = "1.1.25" dependencies = [ "clap", + "clap_lex", "concat-in-place", "dbus", "dbus-crossroads", "dbus-tokio", "fern", "futures", + "futures-lite", "hidapi", "inotify", "intel-pstate", @@ -584,31 +1130,47 @@ dependencies = [ "sysfs-class", "thiserror", "tokio", + "upower_dbus", + "zbus", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -617,9 +1179,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.21.2" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" dependencies = [ "autocfg", "libc", @@ -628,25 +1190,93 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "toml" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uds_windows" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +dependencies = [ + "tempfile", + "winapi", +] + [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "upower_dbus" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b1d77de98ab2e5187f5fa2b045b8c4eecfc49e5ccd07f16f4c89f008116f8c" +dependencies = [ + "serde", + "serde_repr", + "zbus", +] [[package]] name = "version_check" @@ -654,12 +1284,27 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "winapi" version = "0.3.9" @@ -708,42 +1353,130 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "zbus" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "379d587c0ccb632d1179cf44082653f682842f0535f0fdfaefffc34849cc855e" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-recursion", + "async-task", + "async-trait", + "byteorder", + "derivative", + "dirs", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "once_cell", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66492a2e90c0df7190583eccb8424aa12eb7ff06edea415a4fff6688fae18cf8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "zbus_names" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f34f314916bd89bdb9934154627fab152f4f28acdda03e7c4c68181b214fe7e3" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zvariant" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576cc41e65c7f283e5460f5818073e68fb1f1631502b969ef228c2e03c862efb" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd4aafc0dee96ae7242a24249ce9babf21e1562822f03df650d4e68c20e41ed" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index fe6b05cc..e7fb6f49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,25 +1,31 @@ [package] name = "system76-power" -version = "1.1.24" +version = "1.1.25" authors = ["Jeremy Soller "] edition = "2021" [dependencies] -clap = { version = "4.0.19", features = ["derive"] } +# Requires 1.64.0 to update +clap = { version = "=4.0.32", features = ["derive"] } +# Remove after updating to 1.64.0 +clap_lex = "=0.3.0" concat-in-place = "1.1.0" dbus = "0.9" dbus-crossroads = "0.5" dbus-tokio = "0.7" fern = "0.6" futures = "0.3" -hidapi = "1.4" +futures-lite = "1.12.0" +hidapi = "2.1.1" inotify = "0.10" intel-pstate = "1.0.1" libc = "0.2" log = "0.4" -once_cell = "1.16.0" +once_cell = "1.17.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sysfs-class = { git = "https://github.com/pop-os/sysfs-class" } thiserror = "1.0" -tokio = { version = "1.21", features = ["macros", "rt", "time", "signal"] } +tokio = { version = "1.24", features = ["macros", "rt", "time", "signal"] } +upower_dbus = "0.3.2" +zbus = "3.7.0" diff --git a/debian/control b/debian/control index a7188f85..a1e9a773 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Build-Depends: cargo, libdbus-1-dev, libusb-1.0-0-dev, + libudev-dev, pkg-config Standards-Version: 4.1.1 Homepage: https://github.com/pop-os/system76-power @@ -18,6 +19,7 @@ Provides: nvidia-prime Replaces: nvidia-prime Depends: dbus, + libudev1 | libudev0, systemd, ${misc:Depends}, ${shlibs:Depends} diff --git a/examples/hid.rs b/examples/hid.rs index ab7a7704..fabf973c 100644 --- a/examples/hid.rs +++ b/examples/hid.rs @@ -1,3 +1,2 @@ -use system76_power::hid_backlight; - -fn main() { hid_backlight::daemon(); } +#[tokio::main(flavor = "current_thread")] +async fn main() { system76_power::hid_backlight::daemon().await; } diff --git a/examples/hotplug.rs b/examples/hotplug.rs new file mode 100644 index 00000000..0bd37934 --- /dev/null +++ b/examples/hotplug.rs @@ -0,0 +1,17 @@ +use system76_power::hotplug; + +fn main() -> hotplug::Result<()> { + let nvidia_device_id = std::fs::read_to_string("/sys/bus/pci/devices/0000:01:00.0/device").ok(); + + let mut emitter = hotplug::Emitter::new(nvidia_device_id); + + loop { + std::thread::sleep(std::time::Duration::from_secs(1)); + + for id in emitter.emit_on_detect() { + println!("HotPlugDetect: {id}"); + } + + emitter.mux_step(); + } +} diff --git a/src/cpufreq.rs b/src/cpufreq.rs index 561aa369..4b23a484 100644 --- a/src/cpufreq.rs +++ b/src/cpufreq.rs @@ -1,6 +1,20 @@ // Copyright 2022 System76 // SPDX-License-Identifier: GPL-3.0-only +/// Controls frequency boosting functionality. +pub mod boost { + /// Enables frequency boosting + pub fn enable() { write(b"1"); } + + /// Disables frequency boosting + pub fn disable() { write(b"0"); } + + #[inline] + fn write(value: &[u8]) { + let _res = std::fs::write("/sys/devices/system/cpu/cpufreq/boost", value); + } +} + use crate::{util::write_value, Profile}; use concat_in_place::strcat; use std::{ diff --git a/src/daemon/interrupt.rs b/src/daemon/interrupt.rs new file mode 100644 index 00000000..59fd979d --- /dev/null +++ b/src/daemon/interrupt.rs @@ -0,0 +1,25 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use futures::FutureExt; +use std::sync::atomic::{AtomicBool, Ordering}; +use tokio::signal::unix::{signal, SignalKind}; + +pub static CONTINUE: AtomicBool = AtomicBool::new(true); + +pub fn handle() { + let mut int = signal(SignalKind::interrupt()).unwrap(); + let mut hup = signal(SignalKind::hangup()).unwrap(); + let mut term = signal(SignalKind::terminate()).unwrap(); + + tokio::spawn(async move { + let sig = futures::select! { + _ = int.recv().fuse() => "SIGINT", + _ = hup.recv().fuse() => "SIGHUP", + _ = term.recv().fuse() => "SIGTERM" + }; + + log::info!("caught signal: {}", sig); + CONTINUE.store(false, Ordering::SeqCst); + }); +} diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index c85784aa..a93183ba 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -17,55 +17,34 @@ use std::{ atomic::{AtomicBool, Ordering}, Arc, }, - thread, time::Duration, }; -use tokio::{ - signal::unix::{signal, SignalKind}, - time::sleep, -}; use futures::future::FutureExt; +use futures_lite::StreamExt; +use tokio::time::sleep; use crate::{ charge_thresholds::{ get_charge_profiles, get_charge_thresholds, set_charge_thresholds, ChargeProfile, }, - err_str, + cpufreq, err_str, errors::ProfileError, fan::FanDaemon, graphics::{Graphics, GraphicsMode}, - hid_backlight, - hotplug::{mux, Detect, HotPlugDetect}, + hid_backlight, hotplug, kernel_parameters::{KernelParameter, NmiWatchdog}, polkit, Power, DBUS_IFACE, DBUS_NAME, DBUS_PATH, }; -mod profiles; +mod interrupt; +use self::interrupt::CONTINUE; +mod profiles; use self::profiles::{balanced, battery, performance}; const THRESHOLD_POLICY: &str = "com.system76.powerdaemon.set-charge-thresholds"; -static CONTINUE: AtomicBool = AtomicBool::new(true); - -fn signal_handling() { - let mut int = signal(SignalKind::interrupt()).unwrap(); - let mut hup = signal(SignalKind::hangup()).unwrap(); - let mut term = signal(SignalKind::terminate()).unwrap(); - - tokio::spawn(async move { - let sig = futures::select! { - _ = int.recv().fuse() => "SIGINT", - _ = hup.recv().fuse() => "SIGHUP", - _ = term.recv().fuse() => "SIGTERM" - }; - - log::info!("caught signal: {}", sig); - CONTINUE.store(false, Ordering::SeqCst); - }); -} - // Disabled by default because some systems have quirky ACPI tables that fail to resume from // suspension. static PCI_RUNTIME_PM: AtomicBool = AtomicBool::new(false); @@ -75,9 +54,9 @@ pub(crate) fn pci_runtime_pm_support() -> bool { PCI_RUNTIME_PM.load(Ordering::S struct PowerDaemon { initial_set: bool, + on_battery: bool, graphics: Graphics, power_profile: String, - profile_errors: Vec, dbus_connection: Arc, } @@ -86,16 +65,16 @@ impl PowerDaemon { let graphics = Graphics::new().map_err(err_str)?; Ok(PowerDaemon { initial_set: false, + on_battery: false, graphics, power_profile: String::new(), - profile_errors: Vec::new(), dbus_connection, }) } fn apply_profile( &mut self, - func: fn(&mut Vec, bool), + func: fn(&mut Vec, bool, bool), name: &str, ) -> Result<(), String> { if self.power_profile == name { @@ -103,7 +82,9 @@ impl PowerDaemon { return Ok(()); } - func(&mut self.profile_errors, self.initial_set); + let mut profile_errors = Vec::new(); + + func(&mut profile_errors, self.on_battery, self.initial_set); let message = Message::new_signal(DBUS_PATH, DBUS_NAME, "PowerProfileSwitch").unwrap().append1(name); @@ -114,17 +95,40 @@ impl PowerDaemon { self.power_profile = name.into(); - if self.profile_errors.is_empty() { + if profile_errors.is_empty() { Ok(()) } else { let mut error_message = String::from("Errors found when setting profile:"); - for error in self.profile_errors.drain(..) { + for error in profile_errors.drain(..) { error_message = format!("{}\n - {}", error_message, error); } Err(error_message) } } + + /// Called when the status changes between AC and battery. + /// + /// We want to disable CPU frequency boosting if the system is on + /// battery power when the Battery profile is in use. + fn on_battery_changed(&mut self, on_battery: bool) { + self.on_battery = on_battery; + + if self.power_profile == "Battery" { + // intel_pstate has its own mechanism for managing boost. + if let Ok(pstate) = intel_pstate::PState::new() { + let _res = pstate.set_no_turbo(on_battery); + + return; + } + + if on_battery { + cpufreq::boost::disable(); + } else { + cpufreq::boost::enable(); + } + } + } } impl Power for PowerDaemon { @@ -204,7 +208,7 @@ impl Power for PowerDaemon { #[tokio::main(flavor = "current_thread")] #[allow(clippy::too_many_lines)] pub async fn daemon() -> Result<(), String> { - signal_handling(); + interrupt::handle(); let pci_runtime_pm = std::env::var("S76_POWER_PCI_RUNTIME_PM").ok().map_or(false, |v| v == "1"); log::info!( @@ -222,6 +226,9 @@ pub async fn daemon() -> Result<(), String> { }); let mut daemon = PowerDaemon::new(c.clone())?; + + let mut on_battery_stream = on_battery_stream(&mut daemon).await; + let nvidia_exists = !daemon.graphics.nvidia.is_empty(); log::info!("Disabling NMI Watchdog (for kernel debugging only)"); @@ -314,62 +321,61 @@ pub async fn daemon() -> Result<(), String> { cr.insert(DBUS_PATH, &[iface_token], daemon); let cr = Arc::new(std::sync::Mutex::new(cr)); - c.start_receive( - MatchRule::new_method_call(), - Box::new(move |msg, c| { - cr.lock().unwrap().handle_message(msg, c).unwrap(); - true - }), - ); - - // Spawn hid backlight daemon - let _hid_backlight = thread::spawn(hid_backlight::daemon); - let mut fan_daemon = FanDaemon::new(nvidia_exists); + { + let cr = cr.clone(); + c.start_receive( + MatchRule::new_method_call(), + Box::new(move |msg, c| { + cr.lock().unwrap().handle_message(msg, c).unwrap(); + true + }), + ); + } - let mut hpd_res = unsafe { HotPlugDetect::new(nvidia_device_id) }; + // Spawn the HID backlight daemon. + let _hid_backlight_task = tokio::spawn(hid_backlight::daemon()); - let mux_res = unsafe { mux::DisplayPortMux::new() }; + // Initialize the hotplug signal emitter. + let mut hotplug_emitter = hotplug::Emitter::new(nvidia_device_id); - let mut hpd = || -> [bool; 4] { - if let Ok(ref mut hpd) = hpd_res { - unsafe { hpd.detect() } - } else { - [false; 4] - } - }; - - let mut last = hpd(); + // Initialize the fan management daemon. + let mut fan_daemon = FanDaemon::new(nvidia_exists); - log::info!("Handling dbus requests"); while CONTINUE.load(Ordering::SeqCst) { sleep(Duration::from_millis(1000)).await; - fan_daemon.step(); - - let hpd = hpd(); - for i in 0..hpd.len() { - if hpd[i] != last[i] && hpd[i] { - log::info!("HotPlugDetect {}", i); - c.send( - Message::new_signal(DBUS_PATH, DBUS_NAME, "HotPlugDetect") - .unwrap() - .append1(i as u64), - ) - .map_err(|()| "failed to send message".to_string())?; + // Notify the daemon on battery status changes + if let Some(stream) = on_battery_stream.as_mut() { + if let Some(Some(property_changed)) = stream.next().now_or_never() { + if let Ok(on_battery) = property_changed.get().await { + if let Some(daemon) = + cr.lock().unwrap().data_mut::(&dbus::Path::from(DBUS_PATH)) + { + daemon.on_battery_changed(on_battery); + } + } } } - last = hpd; + fan_daemon.step(); + + for id in hotplug_emitter.emit_on_detect() { + log::info!("HotPlugDetect {}", id); + let result = c.send( + Message::new_signal(DBUS_PATH, DBUS_NAME, "HotPlugDetect") + .unwrap() + .append1(id as u64), + ); - if let Ok(ref mux) = mux_res { - unsafe { - mux.step(); + if result.is_err() { + log::error!("failed to send HotPlugDetect signal"); } } + + hotplug_emitter.mux_step(); } - log::info!("daemon exited from loop"); Ok(()) } @@ -429,3 +435,19 @@ fn sync_set_method( { sync_method(b, name, (input_arg,), (), move |d, (arg,)| f(d, arg)); } + +/// Create a stream for listening to battery AC events. +async fn on_battery_stream( + daemon: &mut PowerDaemon, +) -> Option> { + if let Ok(connection) = zbus::Connection::system().await { + if let Ok(proxy) = upower_dbus::UPowerProxy::new(&connection).await { + if let Ok(on_battery) = proxy.on_battery().await { + daemon.on_battery_changed(on_battery); + return Some(proxy.receive_on_battery_changed().await); + } + } + } + + None +} diff --git a/src/daemon/profiles.rs b/src/daemon/profiles.rs index 9f5c181e..eec5c409 100644 --- a/src/daemon/profiles.rs +++ b/src/daemon/profiles.rs @@ -33,7 +33,7 @@ macro_rules! catch { } /// Sets parameters for the balanced profile. -pub fn balanced(errors: &mut Vec, set_brightness: bool) { +pub fn balanced(errors: &mut Vec, _on_battery: bool, set_brightness: bool) { // Use the ACPI Platform Profile if the hardware is supported by the kernel. if crate::acpi_platform::supported() { crate::acpi_platform::balanced(); @@ -92,7 +92,7 @@ pub fn balanced(errors: &mut Vec, set_brightness: bool) { } /// Sets parameters for the performance profile -pub fn performance(errors: &mut Vec, _set_brightness: bool) { +pub fn performance(errors: &mut Vec, _on_battery: bool, _set_brightness: bool) { // Use the ACPI Platform Profile if the hardware is supported by the kernel. if crate::acpi_platform::supported() { crate::acpi_platform::performance(); @@ -124,7 +124,7 @@ pub fn performance(errors: &mut Vec, _set_brightness: bool) { } /// Sets parameters for the battery profile -pub fn battery(errors: &mut Vec, set_brightness: bool) { +pub fn battery(errors: &mut Vec, on_battery: bool, set_brightness: bool) { // Use the ACPI Platform Profile if the hardware is supported by the kernel. if crate::acpi_platform::supported() { crate::acpi_platform::battery(); @@ -138,7 +138,9 @@ pub fn battery(errors: &mut Vec, set_brightness: bool) { catch!( errors, - pstate_values(PStateValues::default().min_perf_pct(0).max_perf_pct(50).no_turbo(true)) + pstate_values( + PStateValues::default().min_perf_pct(0).max_perf_pct(50).no_turbo(on_battery) + ) ); if set_brightness { diff --git a/src/hid_backlight.rs b/src/hid_backlight.rs index 2f3bf437..e47a9d5b 100644 --- a/src/hid_backlight.rs +++ b/src/hid_backlight.rs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-only +use futures_lite::StreamExt; use hidapi::{HidApi, HidDevice, HidResult}; use inotify::{Inotify, WatchMask}; use std::{fs, path::Path}; @@ -55,7 +56,7 @@ fn lightguide(device: &HidDevice, brightness: u8, color: u32) -> HidResult<()> { } // TODO: better error handling -pub fn daemon() { +pub async fn daemon() { let api = match HidApi::new() { Ok(ok) => ok, Err(err) => { @@ -121,8 +122,12 @@ pub fn daemon() { break; } - for event in inotify.read_events_blocking(&mut buffer).unwrap() { + let mut event_stream = inotify.event_stream(&mut buffer).unwrap(); + + while let Some(event) = event_stream.next().await { log::trace!("{:?}", event); } + + tokio::task::yield_now().await; } } diff --git a/src/hotplug/emitter.rs b/src/hotplug/emitter.rs new file mode 100644 index 00000000..edf129e9 --- /dev/null +++ b/src/hotplug/emitter.rs @@ -0,0 +1,54 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use super::{ + mux::{self, DisplayPortMux}, + Detect, HotPlugDetect, +}; + +pub struct Emitter { + last_detection: [bool; 4], + last_result: super::Result, + mux_result: super::Result, +} + +impl Emitter { + #[must_use] + pub fn new(nvidia_device_id: Option) -> Self { + let mut emitter = Self { + last_result: unsafe { HotPlugDetect::new(nvidia_device_id) }, + mux_result: unsafe { mux::DisplayPortMux::new() }, + last_detection: [false; 4], + }; + + emitter.last_detection = emitter.detect(); + emitter + } + + pub fn emit_on_detect(&mut self) -> impl Iterator + '_ { + let hotplug_detect = self.detect(); + let last_detection = self.last_detection; + self.last_detection = hotplug_detect; + + (0..hotplug_detect.len()).filter(move |i| { + let i = *i; + hotplug_detect[i] != last_detection[i] && hotplug_detect[i] + }) + } + + pub fn detect(&mut self) -> [bool; 4] { + if let Ok(ref mut hotplug_detect) = self.last_result { + unsafe { hotplug_detect.detect() } + } else { + [false; 4] + } + } + + pub fn mux_step(&self) { + if let Ok(ref mux) = self.mux_result { + unsafe { + mux.step(); + } + } + } +} diff --git a/src/hotplug/mod.rs b/src/hotplug/mod.rs index 14d2ac40..22f52428 100644 --- a/src/hotplug/mod.rs +++ b/src/hotplug/mod.rs @@ -2,15 +2,20 @@ // // SPDX-License-Identifier: GPL-3.0-only +mod emitter; pub mod mux; pub mod sideband; +pub use self::emitter::Emitter; + use sideband::{Sideband, SidebandError, PCR_BASE_ADDRESS}; use std::{ fs, io::{self, Read, Seek}, }; +pub type Result = std::result::Result; + #[derive(Debug, thiserror::Error)] pub enum HotPlugDetectError { #[error("failed to read DMI product version: {}", _0)] @@ -43,7 +48,7 @@ struct Amd { } impl Amd { - unsafe fn new(gpios: Vec) -> Result { + unsafe fn new(gpios: Vec) -> Result { let mem = fs::OpenOptions::new() .read(true) .write(true) @@ -111,7 +116,7 @@ impl HotPlugDetect { /// - If `/sys/class/dmi/id/product_version` cannot be read /// - If `Sideband::new` fails #[allow(clippy::too_many_lines)] - pub unsafe fn new(nvidia_device: Option) -> Result { + pub unsafe fn new(nvidia_device: Option) -> Result { let model = fs::read_to_string("/sys/class/dmi/id/product_version") .map_err(HotPlugDetectError::ProductVersion)?;