1#!/bin/bash
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# Analyze dumpsys output and show the janky frame count.
18
19readonly NON_MAP_ACTIVITY=com.android.car.carlauncher/.AppGridActivity
20readonly MAP_PACKAGE=com.google.android.apps.maps
21readonly MAP_ACTIVITY=${MAP_PACKAGE}/com.google.android.maps.MapsActivity
22readonly CAR_ACTIVITY=com.android.car.carlauncher/.CarLauncher
23
24####################################################
25# Analyze dumpsys and returns total/janky frame counts.
26# Globals:
27#   None
28# Arguments:
29#   PID of map activity of interest
30# Returns:
31#   Total and janky frame count in space-saparated string
32####################################################
33function retrieve_frame() {
34  local start_pattern="Graphics info for pid ([0-9]+)"
35  local start_pattern_found=false
36  local total_frame_pattern="Total frames rendered: ([0-9]+)"
37  local janky_frame_pattern="Janky frames: ([0-9]+)"
38  local total_frame=0
39  local janky_frame=0
40
41  while IFS= read -r line; do
42    # Maps runs under two different users (u0 and u10).
43    # To get information about the map under the user of interest,
44    # the PID is extracted and compared.
45    if [[ ${line} =~ ${start_pattern} ]]; then
46      if [ ${BASH_REMATCH[1]} = "$1" ]; then
47        start_pattern_found=true
48      else
49        start_pattern_found=false
50      fi
51    fi
52    if [[ ${start_pattern_found} = "true" ]]; then
53      if [[ ${line} =~ ${total_frame_pattern} ]]; then
54        total_frame=${BASH_REMATCH[1]}
55      fi
56      if [[ ${line} =~ ${janky_frame_pattern} ]]; then
57        janky_frame=${BASH_REMATCH[1]}
58      fi
59    fi
60  done < <(adb shell dumpsys gfxinfo ${MAP_PACKAGE})
61
62  echo "${total_frame} ${janky_frame}"
63}
64
65echo "Testing...."
66
67# Launch full-screen map.
68# Starting full-screen map directly doesn't work due to some reasons.
69# We need to kill the map when no map is shown and re-start map activity.
70adb shell am start -n ${NON_MAP_ACTIVITY} &> /dev/null
71# Wait until non-map activity is fully started.
72sleep 2
73adb shell am force-stop ${MAP_PACKAGE} &> /dev/null
74adb shell am start -n ${MAP_ACTIVITY} &> /dev/null
75# Wait until map activity is fully started.
76sleep 7
77
78# Get PID of map under user 10.
79readonly PS_INFO=($(adb shell ps -ef | fgrep ${MAP_PACKAGE} | fgrep u10))
80readonly MAP_PID=${PS_INFO[1]}
81
82if [[ -z ${MAP_PID} ]]; then
83  echo "Map is not found. Test terminates."
84  exit 1
85fi
86
87RET_VAL=($(retrieve_frame ${MAP_PID}))
88readonly OLD_TOTAL_FRAME=${RET_VAL[0]}
89readonly OLD_JANKY_FRAME=${RET_VAL[1]}
90
91# Get screen size.
92readonly SIZE_PATTERN="Physical size: ([0-9]+)x([0-9]+)"
93readonly WM_SIZE=$(adb shell wm size)
94if [[ ${WM_SIZE} =~ ${SIZE_PATTERN} ]]; then
95  SCREEN_WIDTH=${BASH_REMATCH[1]}
96  SCREEN_HEIGHT=${BASH_REMATCH[2]}
97else
98  echo "Test terminates due to failing to get screen size."
99  exit 1
100fi
101
102readonly LEFT_POS=$(awk -v width=${SCREEN_WIDTH} 'BEGIN {printf "%d", width * 0.2}')
103readonly RIGHT_POS=$(awk -v width=${SCREEN_WIDTH} 'BEGIN {printf "%d", width * 0.8}')
104readonly VERTICAL_MID_POS=$(awk -v height=${SCREEN_HEIGHT} 'BEGIN {printf "%d", height * 0.5}')
105readonly SWIPE_DURATION=100
106
107# Send input signal to scroll map.
108COUNTER=0
109while [[ $COUNTER -lt 10 ]]; do
110  adb shell input swipe ${LEFT_POS} ${VERTICAL_MID_POS} ${RIGHT_POS} ${VERTICAL_MID_POS} ${SWIPE_DURATION}
111  sleep 0.5
112  ((COUNTER++))
113done
114
115COUNTER=0
116while [[ $COUNTER -lt 10 ]]; do
117  adb shell input swipe ${RIGHT_POS} ${VERTICAL_MID_POS} ${LEFT_POS} ${VERTICAL_MID_POS} ${SWIPE_DURATION}
118  sleep 0.5
119  ((COUNTER++))
120done
121
122# Make sure that map drawing is finished.
123sleep 3
124
125RET_VAL=($(retrieve_frame ${MAP_PID}))
126readonly CUR_TOTAL_FRAME=${RET_VAL[0]}
127readonly CUR_JANKY_FRAME=${RET_VAL[1]}
128
129if [[ ${CUR_TOTAL_FRAME} = ${OLD_TOTAL_FRAME} ]]; then
130  echo "Map has not been updated. Test failed."
131  exit 1
132fi
133
134readonly TOTAL_COUNT=$((CUR_TOTAL_FRAME - OLD_TOTAL_FRAME))
135readonly JANKY_COUNT=$((CUR_JANKY_FRAME - OLD_JANKY_FRAME))
136
137echo "Janky frame count: ${JANKY_COUNT} out of ${TOTAL_COUNT}"
138
139# Let car launcher take the screen.
140adb shell am start -n ${CAR_ACTIVITY} &> /dev/null
141