Skip to content

Commit

Permalink
Merge pull request #2 from KaustubhPatange/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
KaustubhPatange authored Mar 16, 2021
2 parents 247dec0 + 7112ff8 commit 1de4c9c
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 131 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/choco.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
# Create the nupkg
cd choco
cpack
choco pack aow.nuspec
move *.nupkg aow.nupkg
dir
choco push aow.nupkg --source https://push.chocolatey.org/
Expand Down
47 changes: 29 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
chrono = "0.4.19"

[target.'cfg(windows)'.dependencies]
wfd = "0.1.7"

# Only change version when you are about to release because the next CI
# build will automatically create a draft release & publish to chocolatey.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
<a href="https://crates.io/crates/aow"><img src="https://img.shields.io/crates/v/aow.svg" alt="cargo"></a>
![CI](https://github.com/KaustubhPatange/aow/workflows/CI/badge.svg)

A command line tool written in `Rust` for adb to connect device to your machine over wifi.
A command line tool written in **Rust** for adb to connect device to your machine over wifi.

I generally made this to satisfy my purpose _"to not use a cable when debugging app in Android studio"_. The tool is still in it's early stage & will be actively developed as this is my to-go program to quickly connect a device over wifi.
On top of that it can do a lot of things (check full menu [here](https://github.com/KaustubhPatange/aow/wiki/Command-line-options)) for eg Taking a snapshot & testing deeplinks.

The program also verifies whether your device is not connected over wifi or some similar checks with _Hints_ on how to fix them. It can smartly notify you about the new version available.

If it detects more than one device then the menu will change to "choose a device" mode.
The program is made to handle multiple connected devices & also provide some _Hints_ if any error occurs with `adb`. It can smartly notify you about the new version available.

The usage of the program (after [installation](#Installation)) is pretty simple. Just connect a device > open a terminal & type `aow`. For more options read [here](https://github.com/KaustubhPatange/aow/wiki/Command-line-options).

Expand Down
68 changes: 63 additions & 5 deletions src/back/command.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::back::device::Device;
use crate::back::connect::disconnect;
use std::process::{Command, exit};
use std::path::Path;
use crate::back::dialog::launch_windows_save_dialog;

pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");

Expand All @@ -10,6 +13,18 @@ pub fn parse_command(c: &Vec<String>) {
let _ = show_connected_device();
} else if c[1].eq("-v") || c[1].eq("--version") {
println!("{}", VERSION)
} else if c[1].eq("snap") { // snap
if c.len() == 3 {
take_snap(c[2].as_str());
} else {
take_snap("");
}
} else if c[1].eq("dlk") || c[1].eq("deeplink") { // deeplink
if c.len() == 3 {
deeplink(c[2].as_str())
} else {
println!("- Error: No url attached to the command")
}
} else if c[1].eq("-d") || c[1].eq("--disconnect") {
let result = show_connected_device();
match result {
Expand Down Expand Up @@ -37,18 +52,61 @@ fn show_connected_device() -> Result<Vec<Device>, bool> {
}
}

fn take_snap(file_path: &str) {
let result = Device::get_or_choose_connected_device();
match result {
Some(device) => {
Command::new("adb").arg("-s").arg(device.device_id.as_str()).arg("shell").arg("screencap").arg("-p").arg("/data/local/tmp/file.png").spawn().unwrap().wait().ok();
let save_path: String = if file_path != "" {
String::from(file_path)
} else {
// show save dialog for windows only
let file = match launch_windows_save_dialog() {
Ok(file_path) => {
file_path
}
_ => {
exit(1)
}
};
file
};
Command::new("adb").arg("-s").arg(device.device_id.as_str()).arg("pull").arg("/data/local/tmp/file.png").arg(save_path.as_str()).spawn().unwrap().wait().ok();
if Path::new(save_path.as_str()).exists() {
println!("Saved to: {}", save_path);
} else {
println!("Unknown error while saving file");
}
}
None => {}
}
}

fn deeplink(link: &str) {
match Device::get_or_choose_connected_device() {
None => {}
Some(device) => {
println!("Launching => {}", link);
Command::new("adb").args(&["-s", device.device_id.as_str(), "shell", "am", "start", "-d", link]).spawn().unwrap().wait().ok();
}
}
}

fn print_all_commands() {
println!("ADB Over Wifi (aow) v{} - A command line tool to connect devices over wifi (requires ADB).", VERSION);
println!("Copyright 2020 Kaustubh Patange - https://github.com/KaustubhPatange/aow");
println!();
println!("Usage: aow [options]");
println!();
println!("Options:");
println!(" [null] Connects a device over wifi (see demo on Github)");
println!(" -s, --show Shows the list of connected device over wifi (if any).");
println!(" -d, --disconnect Disconnect the connected device (if any).");
println!(" -v, --version Prints the current version of tool");
println!(" -h, --help Prints this help message.");
println!(" [null] Connects a device over wifi (see demo on Github)");
println!(" -s, --show Shows the list of connected device over wifi (if any).");
println!(" -d, --disconnect Disconnect the connected device (if any).");
println!(" -v, --version Prints the current version of tool");
println!(" -h, --help Prints this help message.");
println!(" snap [file-path] Take a screenshot. Optionally, you can specify a path to save it otherwise");
println!(" the program will open native save dialog (windows only) to save the file.");
println!(" dlk, deeplink [url] Fires a deeplink with the \"url\".");
println!();
println!("Examples:");
println!(" aow");
Expand Down
114 changes: 50 additions & 64 deletions src/back/connect.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::back::device::{Device, Status},
crate::back::device::{Device},
regex::Regex,
std::io::Read,
std::process::{Command, Stdio},
Expand All @@ -8,83 +8,69 @@ use {
};

pub fn connect_device(d: &Device) {
match d.status {
Status::ONLINE => {
if !is_device_connected_to_wifi(d) {
println!("- Error: Device {} is not connected to Wifi", d.device_id);
return;
}

let re = Regex::new(r"inet\s?([\d]{3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})").unwrap();
if !is_device_connected_to_wifi(d) {
println!("- Error: Device {} is not connected to Wifi", d.device_id);
return;
}

let out = Command::new("adb")
.args(&["-s", &d.device_id[..], "shell", "ip", "addr", "show", "wlan0"])
.output()
.unwrap();
let re = Regex::new(r"inet\s?([\d]{3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})").unwrap();

let ip = String::from_utf8_lossy(&out.stdout);
let captures = re.captures(&ip);
match captures {
Some(value) => {
let ip = &value[1];
let out = Command::new("adb")
.args(&["-s", &d.device_id[..], "shell", "ip", "addr", "show", "wlan0"])
.output()
.unwrap();

println!("- address: {}", ip);
println!("Making a connection...");
let ip = String::from_utf8_lossy(&out.stdout);
let captures = re.captures(&ip);
match captures {
Some(value) => {
let ip = &value[1];

let mut child = Command::new("adb")
.arg("connect")
.arg(format!("{}:5555", ip))
.stdout(Stdio::piped())
.spawn()
.unwrap();
println!("- address: {}", ip);
println!("Making a connection...");

let _status_code = match child.wait_timeout(Duration::from_secs(5)).unwrap() {
Some(status) => {
let mut buffer = String::new();
child.stdout.unwrap().read_to_string(&mut buffer).unwrap();
let mut child = Command::new("adb")
.arg("connect")
.arg(format!("{}:5555", ip))
.stdout(Stdio::piped())
.spawn()
.unwrap();

println!("- {}", buffer);
if !buffer.starts_with("cannot connect") {
println!("Hint: Safe to remove the USB cable along with device.");
}else {
println!("Applying fix: killing server");
Command::new("adb").arg("kill-server").spawn().unwrap().wait().ok();
Command::new("adb").arg("tcpip").arg("5555").spawn().unwrap().wait().ok();
println!();
println!("Hint: Try running the command 'aow' again to see if error is fixed.");
}
let _status_code = match child.wait_timeout(Duration::from_secs(5)).unwrap() {
Some(status) => {
let mut buffer = String::new();
child.stdout.unwrap().read_to_string(&mut buffer).unwrap();

status.code()
}
None => {
println!("- Error: Connection timeout!");
println!();
println!("Hint:\n1. {}\n2. {}",
"Disconnect & re-connect your wifi of client device.",
"Check if mobile data is ON along with Wifi (this may sometimes causes a reason for connection failure).");
println!("- {}", buffer);
if !buffer.starts_with("cannot connect") {
println!("Hint: Safe to remove the USB cable along with device.");
} else {
println!("Applying fix: killing server");
Command::new("adb").arg("kill-server").spawn().unwrap().wait().ok();
Command::new("adb").arg("tcpip").arg("5555").spawn().unwrap().wait().ok();
println!();
println!("Hint: Try running the command 'aow' again to see if error is fixed.");
}

child.kill().unwrap();
child.wait().unwrap().code()
}
};
status.code()
}
None => {
println!("- Error: Couldn't find IP address");
println!("- Error: Connection timeout!");
println!();
println!("Hint: If your device is connected to WIFI & still you are getting this error, contact me quickly on Github.");
return;
println!("Hint:\n1. {}\n2. {}",
"Disconnect & re-connect your wifi of client device.",
"Check if mobile data is ON along with Wifi (this may sometimes causes a reason for connection failure).");

child.kill().unwrap();
child.wait().unwrap().code()
}
}
}
Status::OFFLINE => {
println!("- Error: Device {} is offline", d.device_id);
println!();
println!("Hint: Try disconnecting & re-connecting device or use aow -d to disconnect from all devices.")
};
}
Status::UNAUTHORIZED => {
println!("- Error: Device {} is unauthorized", d.device_id);
None => {
println!("- Error: Couldn't find IP address");
println!();
println!("Hint: Accept the prompt in your device & re run the command.")
println!("Hint: If your device is connected to WIFI & still you are getting this error, contact me quickly on Github.");
return;
}
}
}
Expand Down
Loading

0 comments on commit 1de4c9c

Please sign in to comment.