go-mobile-automation/apis/setup.go
2021-12-29 12:51:11 +08:00

174 lines
3.6 KiB
Go

package apis
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
"time"
)
func _split_words(line string) []string {
result := make([]string, 0)
item := new(strings.Builder)
for _, c := range line {
if c != ' ' && c != '\t' {
item.WriteRune(c)
continue
}
if item.Len() == 0 {
continue
}
result = append(result, item.String())
item.Reset()
}
if item.Len() != 0 {
result = append(result, item.String())
}
return result
}
func _kill_process_uiautomator(d *Device) error {
out, err := d.Shell("ps -A|grep uiautomator")
if err != nil {
return nil
}
lines := strings.Split(out, "\n")
if len(lines) == 0 {
return nil
}
pids := make([]int, 0)
for _, line := range lines {
if line == "" {
continue
}
words := _split_words(line)
pid, err := strconv.Atoi(words[1])
if err != nil {
return err
}
name := words[len(words)-1]
if name == "uiautomator" {
pids = append(pids, pid)
}
}
for _, pid := range pids {
_, err := d.Shell("kill -9 " + strconv.Itoa(pid))
if err != nil {
return err
}
}
return nil
}
func _is_alive(d *Device) (bool, error) {
input := make(map[string]interface{})
input["jsonrpc"] = "2.0"
input["id"] = 1
input["method"] = "deviceInfo"
inputBytes, err := json.Marshal(input)
if err != nil {
return false, err
}
resp, err := http.Post(d.GetHttpRequest().BaseUrl+"/jsonrpc/0", "application/json", bytes.NewBuffer(inputBytes))
if err != nil {
return false, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return false, nil
}
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
var resMap map[string]interface{}
err = json.Unmarshal(bytes, &resMap)
if err != nil {
return false, err
}
if _, ok := resMap["error"]; ok {
return false, nil
}
return true, nil
}
func _force_reset_uiautomator_v2(d *Device, s *Service, launch_test_app bool) (bool, error) {
package_name := "com.github.uiautomator"
info, err := s.Stop()
if err != nil {
return false, err
}
if !info.Success {
return false, errors.New(strings.ToLower(info.Description))
}
err = _kill_process_uiautomator(d)
if err != nil {
return false, err
}
if launch_test_app {
for _, permission := range []string{"android.permission.SYSTEM_ALERT_WINDOW",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.READ_PHONE_STATE"} {
_, err = d.Shell("pm grant " + package_name + " " + permission)
if err != nil {
fmt.Println(err)
}
}
_, err = d.Shell("am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n " + package_name + "/.ToastActivity")
if err != nil {
return false, err
}
}
info, err = s.Start()
if err != nil {
return false, err
}
if !info.Success {
return false, errors.New(strings.ToLower(info.Description))
}
time.Sleep(500 * time.Millisecond)
flow_window_showed := false
now := time.Now()
deadline := now.Add(40 * time.Second)
for time.Now().Before(deadline) {
fmt.Printf("uiautomator-v2 is starting ... left: %ds\n", int(deadline.UnixMilli()-time.Now().UnixMilli())/1000)
running, err := s.Running()
if err != nil {
return false, err
}
if !running {
break
}
time.Sleep(time.Second)
alive, err := _is_alive(d)
if err != nil {
return false, err
}
if !alive {
continue
}
if !flow_window_showed {
flow_window_showed = true
err = d.ShowFloatWindow(true)
if err != nil {
return false, err
}
fmt.Println("show float window")
time.Sleep(time.Second)
continue
}
return true, nil
}
_, err = s.Stop()
if err != nil {
return false, err
}
return false, nil
}