|
1 | 1 | use crate::{constants, utils};
|
2 | 2 | use anyhow::{bail, Result};
|
3 |
| -use nix::unistd::{getgid, getuid}; |
| 3 | +use nix::unistd::{getgid, getuid, Pid}; |
4 | 4 | use std::process::{Child, Command};
|
5 | 5 | use std::sync::mpsc;
|
6 | 6 | use std::{fs, thread};
|
7 | 7 | use std::os::unix::net::UnixListener;
|
8 |
| -use std::path::Path; |
9 | 8 | use std::time::Duration;
|
| 9 | +use binder::IBinder; |
| 10 | +use nix::sys::signal::{kill, Signal}; |
10 | 11 |
|
11 | 12 | static mut LOCK: Option<UnixListener> = None;
|
12 | 13 |
|
@@ -49,36 +50,56 @@ fn ensure_single_instance() -> Result<()> {
|
49 | 50 | }
|
50 | 51 |
|
51 | 52 | fn spawn_daemon() -> Result<()> {
|
52 |
| - let daemon32 = Command::new(constants::PATH_ZYGISKD32).arg("daemon").spawn(); |
53 |
| - let daemon64 = Command::new(constants::PATH_ZYGISKD64).arg("daemon").spawn(); |
54 |
| - let (sender, receiver) = mpsc::channel(); |
55 |
| - let mut waiting = vec![]; |
56 |
| - let mut spawn = |mut daemon: Child, socket: &'static str| { |
57 |
| - waiting.push(socket); |
58 |
| - let sender = sender.clone(); |
59 |
| - thread::spawn(move || { |
60 |
| - let result = daemon.wait().unwrap(); |
61 |
| - log::error!("Daemon process {} died: {}", daemon.id(), result); |
62 |
| - drop(daemon); |
63 |
| - sender.send(()).unwrap(); |
64 |
| - }); |
65 |
| - }; |
66 |
| - if let Ok(it) = daemon32 { spawn(it, "/dev/socket/zygote_secondary") } |
67 |
| - if let Ok(it) = daemon64 { spawn(it, "/dev/socket/zygote") } |
| 53 | + let mut lives = 5; |
| 54 | + loop { |
| 55 | + let daemon32 = Command::new(constants::PATH_ZYGISKD32).arg("daemon").spawn(); |
| 56 | + let daemon64 = Command::new(constants::PATH_ZYGISKD64).arg("daemon").spawn(); |
| 57 | + let mut child_ids = vec![]; |
| 58 | + let (sender, receiver) = mpsc::channel(); |
| 59 | + let mut spawn = |mut daemon: Child| { |
| 60 | + child_ids.push(daemon.id()); |
| 61 | + let sender = sender.clone(); |
| 62 | + thread::spawn(move || { |
| 63 | + let result = daemon.wait().unwrap(); |
| 64 | + log::error!("Daemon process {} died: {}", daemon.id(), result); |
| 65 | + drop(daemon); |
| 66 | + let _ = sender.send(()); |
| 67 | + }); |
| 68 | + }; |
| 69 | + if let Ok(it) = daemon32 { spawn(it) } |
| 70 | + if let Ok(it) = daemon64 { spawn(it) } |
68 | 71 |
|
69 |
| - waiting.into_iter().for_each(|socket| wait_zygote(socket)); |
70 |
| - log::info!("Zygote ready, restore native bridge"); |
71 |
| - utils::restore_native_bridge()?; |
| 72 | + let mut binder = loop { |
| 73 | + if receiver.try_recv().is_ok() { |
| 74 | + bail!("Daemon died before system server ready"); |
| 75 | + } |
| 76 | + match binder::get_service("activity") { |
| 77 | + Some(binder) => break binder, |
| 78 | + None => { |
| 79 | + log::trace!("System server not ready, wait for 1s..."); |
| 80 | + thread::sleep(Duration::from_secs(1)); |
| 81 | + } |
| 82 | + }; |
| 83 | + }; |
| 84 | + log::info!("System server ready, restore native bridge"); |
| 85 | + utils::set_property(constants::PROP_NATIVE_BRIDGE, &utils::get_native_bridge())?; |
72 | 86 |
|
73 |
| - let _ = receiver.recv(); |
74 |
| - bail!("Daemon process died"); |
75 |
| -} |
| 87 | + loop { |
| 88 | + if receiver.try_recv().is_ok() || binder.ping_binder().is_err() { break; } |
| 89 | + thread::sleep(Duration::from_secs(1)) |
| 90 | + } |
| 91 | + for child in child_ids { |
| 92 | + let _ = kill(Pid::from_raw(child as i32), Signal::SIGKILL); |
| 93 | + } |
76 | 94 |
|
77 |
| -fn wait_zygote(socket: &str) -> () { |
78 |
| - let path = Path::new(socket); |
79 |
| - loop { |
80 |
| - if path.exists() { return; } |
81 |
| - log::debug!("{socket} not exists, wait for 1s..."); |
82 |
| - thread::sleep(Duration::from_secs(1)); |
| 95 | + lives -= 1; |
| 96 | + if lives == 0 { |
| 97 | + bail!("Too many crashes, abort"); |
| 98 | + } |
| 99 | + |
| 100 | + log::error!("Restarting zygote..."); |
| 101 | + utils::set_property(constants::PROP_NATIVE_BRIDGE, constants::ZYGISK_LOADER)?; |
| 102 | + utils::set_property(constants::PROP_SVC_ZYGOTE, "restart")?; |
| 103 | + thread::sleep(Duration::from_secs(2)); |
83 | 104 | }
|
84 | 105 | }
|
0 commit comments