-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add install and fix screenshot on lower device
- Loading branch information
1 parent
98232d1
commit a9c9b59
Showing
6 changed files
with
367 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net" | ||
"os" | ||
"os/exec" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
const ( | ||
_OKAY = "OKAY" | ||
_FAIL = "FAIL" | ||
) | ||
|
||
func adbCommand(serial string, args ...string) *exec.Cmd { | ||
fmt.Println("+ adb", "-s", serial, strings.Join(args, " ")) | ||
c := exec.Command(adbPath(), args...) | ||
c.Env = append(os.Environ(), "ANDROID_SERIAL="+serial) | ||
return c | ||
} | ||
|
||
func panicError(e error) { | ||
if e != nil { | ||
panic(e) | ||
} | ||
} | ||
|
||
type AdbConnection struct { | ||
net.Conn | ||
} | ||
|
||
// SendPacket data is like "000chost:version" | ||
func (conn *AdbConnection) SendPacket(data string) error { | ||
pktData := fmt.Sprintf("%04x%s", len(data), data) | ||
_, err := conn.Write([]byte(pktData)) | ||
return err | ||
} | ||
|
||
func (conn *AdbConnection) readN(n int) (v string, err error) { | ||
buf := make([]byte, n) | ||
_, err = io.ReadFull(conn, buf) | ||
if err != nil { | ||
return | ||
} | ||
return string(buf), nil | ||
} | ||
|
||
func (conn *AdbConnection) readString() (string, error) { | ||
hexlen, err := conn.readN(4) | ||
if err != nil { | ||
return "", err | ||
} | ||
var length int | ||
_, err = fmt.Sscanf(hexlen, "%04x", &length) | ||
if err != nil { | ||
return "", err | ||
} | ||
return conn.readN(length) | ||
} | ||
|
||
// RecvPacket receive data like "OKAY00040028" | ||
func (conn *AdbConnection) RecvPacket() (data string, err error) { | ||
stat, err := conn.readN(4) | ||
if err != nil { | ||
return "", err | ||
} | ||
switch stat { | ||
case _OKAY: | ||
return conn.readString() | ||
case _FAIL: | ||
data, err = conn.readString() | ||
if err != nil { | ||
return | ||
} | ||
err = errors.New(data) | ||
return | ||
default: | ||
return "", fmt.Errorf("Unknown stat: %s", strconv.Quote(stat)) | ||
} | ||
} | ||
|
||
type AdbClient struct { | ||
Addr string | ||
} | ||
|
||
func NewAdbClient() *AdbClient { | ||
return &AdbClient{ | ||
Addr: "127.0.0.1:5037", | ||
} | ||
} | ||
|
||
var DefaultAdbClient = &AdbClient{ | ||
Addr: "127.0.0.1:5037", | ||
} | ||
|
||
func (c *AdbClient) newConnection() (conn *AdbConnection, err error) { | ||
netConn, err := net.Dial("tcp", c.Addr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &AdbConnection{netConn}, nil | ||
} | ||
|
||
// Version returns adb server version | ||
func (c *AdbClient) Version() (string, error) { | ||
conn, err := c.newConnection() | ||
if err != nil { | ||
return "", err | ||
} | ||
if err := conn.SendPacket("host:version"); err != nil { | ||
return "", err | ||
} | ||
return conn.RecvPacket() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
module github.com/codeskyblue/fa | ||
|
||
require ( | ||
github.com/cavaliercoder/grab v2.0.0+incompatible | ||
github.com/manifoldco/promptui v0.3.2 | ||
gopkg.in/urfave/cli.v1 v1.20.0 | ||
github.com/mattn/go-runewidth v0.0.3 // indirect | ||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 | ||
github.com/pkg/errors v0.8.0 | ||
github.com/shogo82148/androidbinary v0.0.0-20180627093851-01c4bfa8b3b5 | ||
github.com/urfave/cli v1.20.0 | ||
gopkg.in/cheggaaa/pb.v1 v1.0.25 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"os" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
"github.com/cavaliercoder/grab" | ||
"github.com/pkg/errors" | ||
"github.com/shogo82148/androidbinary/apk" | ||
"github.com/urfave/cli" | ||
pb "gopkg.in/cheggaaa/pb.v1" | ||
) | ||
|
||
func httpDownload(dst string, url string) (resp *grab.Response, err error) { | ||
client := grab.NewClient() | ||
req, err := grab.NewRequest(dst, url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// start download | ||
resp = client.Do(req) | ||
fmt.Printf("Downloading %v...\n", resp.Filename) | ||
|
||
// start UI loop | ||
t := time.NewTicker(500 * time.Millisecond) | ||
defer t.Stop() | ||
|
||
bar := pb.New(int(resp.Size)) | ||
bar.SetMaxWidth(80) | ||
bar.ShowSpeed = true | ||
bar.ShowTimeLeft = false | ||
bar.SetUnits(pb.U_BYTES) | ||
bar.Start() | ||
|
||
Loop: | ||
for { | ||
select { | ||
case <-t.C: | ||
bar.Set(int(resp.BytesComplete())) | ||
case <-resp.Done: | ||
bar.Set(int(resp.Size)) | ||
bar.Finish() | ||
break Loop | ||
} | ||
} | ||
// check for errors | ||
if err := resp.Err(); err != nil { | ||
return nil, errors.Wrap(err, "download failed") | ||
} | ||
fmt.Println("Download saved to", resp.Filename) | ||
return resp, err | ||
} | ||
|
||
func actInstall(ctx *cli.Context) error { | ||
if !ctx.Args().Present() { | ||
return errors.New("apkfile or apkurl should provided") | ||
} | ||
serial, err := chooseOne() | ||
if err != nil { | ||
return err | ||
} | ||
arg := ctx.Args().First() | ||
|
||
// download apk | ||
apkpath := arg | ||
if regexp.MustCompile(`^https?://`).MatchString(arg) { | ||
resp, err := httpDownload(".", arg) | ||
if err != nil { | ||
return err | ||
} | ||
apkpath = resp.Filename | ||
} | ||
|
||
// parse apk | ||
pkg, err := apk.OpenFile(apkpath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// handle --force | ||
if ctx.Bool("force") { | ||
pkgName := pkg.PackageName() | ||
adbCommand(serial, "uninstall", pkgName).Run() | ||
} | ||
|
||
// install | ||
outBuffer := bytes.NewBuffer(nil) | ||
c := adbCommand(serial, "install", apkpath) | ||
c.Stdout = io.MultiWriter(os.Stdout, outBuffer) | ||
c.Stderr = os.Stderr | ||
if err := c.Run(); err != nil { | ||
return err | ||
} | ||
|
||
if strings.Contains(outBuffer.String(), "Failure") { | ||
return errors.New("install failed") | ||
} | ||
if ctx.Bool("launch") { | ||
packageName := pkg.PackageName() | ||
mainActivity, er := pkg.MainActivity() | ||
if er != nil { | ||
fmt.Println("apk have no main-activity") | ||
return nil | ||
} | ||
if !strings.Contains(mainActivity, ".") { | ||
mainActivity = "." + mainActivity | ||
} | ||
fmt.Println("Launch app", packageName, "...") | ||
adbCommand(serial, "shell", "am", "start", "-n", packageName+"/"+mainActivity).Run() | ||
} | ||
return nil | ||
} |
Oops, something went wrong.