diff --git a/README.md b/README.md index b5a309f..11dd7fc 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ It's very easy to send and receive files from your android device, for example a JadbDevice device = ... device.pull(new RemoteFile("/path/to/file.txt"), new File("file.txt")); +Some high level operations such as installing and uninstalling packages are also available. + + JadbDevice device = ... + new PackageManager(device).install(new File("/path/to/my.apk")); + ## Protocol Description ## An overview of the protocol can be found here: [Overview](https://github.com/cgjones/android-system-core/blob/master/adb/OVERVIEW.TXT) diff --git a/src/se/vidstige/jadb/Stream.java b/src/se/vidstige/jadb/Stream.java index db807db..5a1a31b 100644 --- a/src/se/vidstige/jadb/Stream.java +++ b/src/se/vidstige/jadb/Stream.java @@ -1,8 +1,10 @@ package se.vidstige.jadb; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; public class Stream { public static void copy(InputStream in, OutputStream out) throws IOException { @@ -13,4 +15,9 @@ public class Stream { } } + public static String readAll(InputStream input, Charset charset) throws IOException { + ByteArrayOutputStream tmp = new ByteArrayOutputStream(); + Stream.copy(input, tmp); + return new String(tmp.toByteArray(), charset); + } } diff --git a/src/se/vidstige/jadb/managers/Bash.java b/src/se/vidstige/jadb/managers/Bash.java new file mode 100644 index 0000000..3f2ef04 --- /dev/null +++ b/src/se/vidstige/jadb/managers/Bash.java @@ -0,0 +1,11 @@ +package se.vidstige.jadb.managers; + +public class Bash { + public static String quote(String s) { + // TODO: Should also check other whitespace + if (!s.contains(" ")) { + return s; + } + return "'" + s.replace("'", "'\\''") + "'"; + } +} diff --git a/src/se/vidstige/jadb/managers/PackageManager.java b/src/se/vidstige/jadb/managers/PackageManager.java index 905a9bb..a1aefc5 100644 --- a/src/se/vidstige/jadb/managers/PackageManager.java +++ b/src/se/vidstige/jadb/managers/PackageManager.java @@ -2,10 +2,10 @@ package se.vidstige.jadb.managers; import se.vidstige.jadb.JadbDevice; import se.vidstige.jadb.JadbException; +import se.vidstige.jadb.RemoteFile; +import se.vidstige.jadb.Stream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @@ -37,4 +37,27 @@ public class PackageManager { } return result; } + + private String getErrorMessage(String operation, String target, String errorMessage) { + return "Could not " + operation + " " + target + ": " + errorMessage; + } + + private void verifyOperation(String operation, String target, String result) throws JadbException { + if (!result.contains("Success")) throw new JadbException(getErrorMessage(operation, target, result)); + } + + public void install(File apkFile) throws IOException, JadbException { + RemoteFile remote = new RemoteFile("/sdcard/tmp/" + apkFile.getName()); + device.push(apkFile, remote); + InputStream s = device.executeShell("pm", "install", Bash.quote(remote.getPath())); + String result = Stream.readAll(s, Charset.forName("UTF-8")); + // TODO: Remove remote file + verifyOperation("install", apkFile.getName(), result); + } + + public void uninstall(Package name) throws IOException, JadbException { + InputStream s = device.executeShell("pm", "uninstall", name.toString()); + String result = Stream.readAll(s, Charset.forName("UTF-8")); + verifyOperation("uninstall", name.toString(), result); + } } diff --git a/test/data/Tiniest Smallest APK ever_v' platformBuildVersionName=_apkpure.com.apk b/test/data/Tiniest Smallest APK ever_v' platformBuildVersionName=_apkpure.com.apk new file mode 100644 index 0000000..966cb99 Binary files /dev/null and b/test/data/Tiniest Smallest APK ever_v' platformBuildVersionName=_apkpure.com.apk differ diff --git a/test/se/vidstige/jadb/test/PackageMangerTests.java b/test/se/vidstige/jadb/test/PackageMangerTests.java index d47e417..6c0a10d 100644 --- a/test/se/vidstige/jadb/test/PackageMangerTests.java +++ b/test/se/vidstige/jadb/test/PackageMangerTests.java @@ -7,6 +7,7 @@ import se.vidstige.jadb.JadbConnection; import se.vidstige.jadb.managers.Package; import se.vidstige.jadb.managers.PackageManager; +import java.io.File; import java.io.IOException; import java.util.List; @@ -37,4 +38,11 @@ public class PackageMangerTests { System.out.println(p); } } + + @Test + public void testInstallUninstallCycle() throws Exception { + File f = new File("test/data/Tiniest Smallest APK ever_v' platformBuildVersionName=_apkpure.com.apk"); + pm.install(f); + pm.uninstall(new Package("b.a")); + } }