aboutsummaryrefslogtreecommitdiffhomepage
path: root/platform_tools/android/bin/android_run_app.go
diff options
context:
space:
mode:
Diffstat (limited to 'platform_tools/android/bin/android_run_app.go')
-rw-r--r--platform_tools/android/bin/android_run_app.go248
1 files changed, 0 insertions, 248 deletions
diff --git a/platform_tools/android/bin/android_run_app.go b/platform_tools/android/bin/android_run_app.go
deleted file mode 100644
index 53ae0fd938..0000000000
--- a/platform_tools/android/bin/android_run_app.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/*
- Run a Skia app to completion, piping the log to stdout.
-*/
-
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "os"
- "os/exec"
- "os/signal"
- "strconv"
- "strings"
- "time"
-
- "github.com/skia-dev/glog"
- "go.skia.org/infra/go/common"
-)
-
-const (
- COM_SKIA = "com.skia"
-)
-
-var (
- adbPath = flag.String("adb", "", "Path to the ADB executable.")
- app = flag.String("app", "VisualBench", "Name of the app to run.")
- serial = flag.String("s", "", "Serial number for the Android device to use.")
-)
-
-// Struct used for running ADB commands.
-type ADB struct {
- path string
- serial string
-}
-
-// ADBFromFlags returns an ADB instance based on flags passed to the program.
-func ADBFromFlags() *ADB {
- rv := &ADB{
- path: *adbPath,
- serial: *serial,
- }
- if rv.path == "" {
- rv.path = "adb"
- }
- return rv
-}
-
-// Cmd creates an exec.Cmd object for the given ADB command.
-func (adb *ADB) Cmd(log bool, args ...string) *exec.Cmd {
- cmd := []string{}
- if adb.serial != "" {
- cmd = append(cmd, "-s", adb.serial)
- }
- cmd = append(cmd, args...)
- if log {
- glog.Infof("Exec `%s %s`", adb.path, strings.Join(cmd, " "))
- }
- return exec.Command(adb.path, cmd...)
-}
-
-// KillSkia kills any running process.
-func (adb *ADB) Kill(proc string) error {
- return adb.Cmd(false, "shell", "am", "force-stop", proc).Run()
-}
-
-// PollSkia checks to see if the given process is running. If so, return the pid, otherwise return -1.
-func (adb *ADB) Poll(proc string) (int64, error) {
- output, err := adb.Cmd(false, "shell", "ps").Output()
- if err != nil {
- return -1, fmt.Errorf("Failed to check the running processes on the device: %v", err)
- }
- for _, line := range strings.Split(string(output), "\n") {
- if strings.Contains(line, proc) {
- fields := strings.Fields(line)
- pid, err := strconv.ParseInt(fields[1], 10, 32)
- if err != nil {
- return -1, fmt.Errorf("Failed to parse \"%s\" to an integer: %v", fields[1], err)
- }
- return pid, nil
- }
- }
- return -1, nil
-}
-
-// ReadLinesFromPipe reads from the given pipe and logs its output.
-func ReadLinesFromPipe(pipe io.Reader, lines chan string) {
- buf := []byte{}
-
- // writeLine recovers from a panic when writing to the channel.
- writeLine := func(s string) {
- defer func() {
- if r := recover(); r != nil {
- glog.Warningf("Panic writing to channel... are we exiting?")
- }
- }()
- lines <- s
- }
-
- // readLines reads output lines from the buffer and pushes them into the channel.
- readlines := func() {
- readIdx := 0
- // Read lines from buf.
- for i, b := range buf {
- if b == '\n' {
- s := string(buf[readIdx:i])
- writeLine(s)
- readIdx = i + 1
- }
- }
- // Remove the lines we read.
- buf = buf[readIdx:]
- }
-
- // Loop forever, reading bytes from the pipe.
- readbuf := make([]byte, 4096)
- for {
- read, err := pipe.Read(readbuf)
- if read > 0 {
- buf = append(buf, readbuf[:read]...)
-
- // Read lines from the buffers.
- readlines()
- }
- if err != nil {
- if err == io.EOF {
- break
- } else {
- glog.Error(err)
- }
- } else if read == 0 {
- time.Sleep(20 * time.Millisecond)
- }
- }
- // Read any remaining lines from the buffers.
- readlines()
- // "Flush" any incomplete lines from the buffers.
- writeLine(string(buf))
-}
-
-// RunApp launches the given app on the device, pipes its log output to stdout,
-// and returns when the app finishes running, with an error if the app did not
-// complete successfully.
-func RunApp(adb *ADB, appName string, args []string) error {
- // Kill any running instances of the app.
- if err := adb.Kill(COM_SKIA); err != nil {
- return fmt.Errorf("Failed to kill app: %v", err)
- }
-
- // Clear the ADB log.
- if err := adb.Cmd(false, "logcat", "-c").Run(); err != nil {
- return fmt.Errorf("Failed to clear ADB log: %v", err)
- }
-
- // Prepare to read the subprocess output.
- logProc := adb.Cmd(false, "logcat")
- defer func() {
- // Cleanup.
- if err := logProc.Process.Kill(); err != nil {
- glog.Errorf("Failed to kill logcat process: %v", err)
- }
- }()
-
- stdout, err := logProc.StdoutPipe()
- if err != nil {
- return fmt.Errorf("Failed to obtain stdout pipe: %v", err)
- }
- stdoutLines := make(chan string)
- stderr, err := logProc.StderrPipe()
- if err != nil {
- return fmt.Errorf("Failed to obtain stderr pipe: %v", err)
- }
- stderrLines := make(chan string)
-
- go ReadLinesFromPipe(stdout, stdoutLines)
- go ReadLinesFromPipe(stderr, stderrLines)
- if err := logProc.Start(); err != nil {
- return fmt.Errorf("Failed to start logcat process.")
- }
-
- // Launch the app.
- stop := make(chan bool, 1)
- activity := fmt.Sprintf("%s.%s/%s.%sActivity", COM_SKIA, strings.ToLower(appName), COM_SKIA, appName)
- flags := strings.Join(args, " ")
- cmd := []string{"shell", "am", "start", "-S", "-n", activity, "--es", "cmdLineFlags", flags}
- output, err := adb.Cmd(true, cmd...).Output()
- if err != nil {
- return fmt.Errorf("Failed to launch app: %v", err)
- }
- glog.Info(string(output))
- // Make a handler for SIGINT so that we can kill the app if this script is interrupted.
- go func() {
- interrupt := make(chan os.Signal, 1)
- signal.Notify(interrupt, os.Interrupt)
- for _ = range interrupt {
- glog.Infof("Received SIGINT; killing app.")
- stop <- true
- close(stdoutLines)
- close(stderrLines)
- if err := adb.Kill(COM_SKIA); err != nil {
- glog.Errorf("Failed to kill app: %v", err)
- }
- if err := logProc.Process.Kill(); err != nil {
- glog.Errorf("Failed to kill logcat process: %v", err)
- }
- }
- }()
-
- // Loop until the app finishes or we're interrupted, writing output as appropriate.
- // TODO(borenet): VisualBench should print its exit code. This script should exit
- // with that code, or a non-zero code if the process ended without printing any code.
- second := time.Tick(time.Second)
-PollLoop:
- for {
- select {
- case <-second:
- // Poll the Skia process every second to make sure it's still running.
- pid, err := adb.Poll(COM_SKIA)
- if err != nil {
- glog.Errorf("Failed to poll Skia process: %v", err)
- } else if pid < 0 {
- glog.Infof("Skia process is no longer running!")
- break PollLoop
- }
- case <-stop:
- break PollLoop
- case line := <-stdoutLines:
- glog.Info(line)
- case line := <-stderrLines:
- glog.Error(line)
- }
- }
-
- return nil
-}
-
-func main() {
- common.Init()
- args := flag.Args()
- if err := RunApp(ADBFromFlags(), *app, args); err != nil {
- glog.Fatal(err)
- }
-}