1#!/usr/bin/env python3
2#
3# Copyright 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"""Helper util libraries for iorapd related operations."""
18
19import os
20import sys
21
22# up to two level
23sys.path.append(os.path.join(os.path.abspath(__file__),'../..'))
24import lib.cmd_utils as cmd_utils
25
26IORAPID_LIB_DIR = os.path.abspath(os.path.dirname(__file__))
27IORAPD_DATA_PATH = '/data/misc/iorapd'
28IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(IORAPID_LIB_DIR,
29                                                         '../common'))
30
31def _iorapd_path_to_data_file(package: str, activity: str, suffix: str) -> str:
32  """Gets conventional data filename.
33
34   Returns:
35     The path of iorapd data file.
36
37  """
38  # Match logic of 'AppComponentName' in iorap::compiler C++ code.
39  return '{}/{}%2F{}.{}'.format(IORAPD_DATA_PATH, package, activity, suffix)
40
41def compile_perfetto_trace_on_device(package: str, activity: str,
42                                     inodes: str) -> bool:
43  """Compiles the perfetto trace using on-device compiler."""
44  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
45                                       'iorapd_compiler_for_app_trace',
46                                       [package, activity, inodes])
47  return passed
48
49def get_iorapd_compiler_trace(package: str, activity: str, dest: str) -> str:
50  """Gets compiler trace to dest file."""
51  src = _iorapd_path_to_data_file(package, activity, 'compiled_trace.pb')
52  passed, _ = cmd_utils.run_shell_command('adb pull "{}" "{}"'.format(src, dest))
53  if not passed:
54    return False
55  return True
56
57def iorapd_compiler_install_trace_file(package: str, activity: str,
58                                       input_file: str) -> bool:
59  """Installs a compiled trace file.
60
61  Returns:
62    Whether the trace file is installed successful or not.
63  """
64  # remote path calculations
65  compiled_path = _iorapd_path_to_data_file(package, activity,
66                                            'compiled_trace.pb')
67
68  if not os.path.exists(input_file):
69    print('Error: File {} does not exist'.format(input_file))
70    return False
71
72  passed, _ = cmd_utils.run_adb_shell_command(
73    'mkdir -p "$(dirname "{}")"'.format(compiled_path))
74  if not passed:
75    return False
76
77  passed, _ = cmd_utils.run_shell_command('adb push "{}" "{}"'.format(
78    input_file, compiled_path))
79
80  return passed
81
82def wait_for_iorapd_finish(package: str,
83                           activity: str,
84                           timeout: int,
85                           debug: bool,
86                           logcat_timestamp: str)->bool:
87  """Waits for the finish of iorapd.
88
89  Returns:
90    A bool indicates whether the iorapd is done successfully or not.
91  """
92  # Set verbose for bash script based on debug flag.
93  if debug:
94    os.putenv('verbose', 'y')
95
96  # Validate that readahead completes.
97  # If this fails for some reason, then this will also discard the timing of
98  # the run.
99  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
100                                       'iorapd_readahead_wait_until_finished',
101                                       [package, activity, logcat_timestamp,
102                                        str(timeout)])
103  return passed
104
105
106def enable_iorapd_readahead() -> bool:
107  """
108  Disable readahead. Subsequent launches of an application will be sped up
109  by iorapd readahead prefetching.
110
111  Returns:
112    A bool indicates whether the enabling is done successfully or not.
113  """
114  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
115                                       'iorapd_readahead_enable', [])
116  return passed
117
118def disable_iorapd_readahead() -> bool:
119  """
120  Disable readahead. Subsequent launches of an application will be not be sped
121  up by iorapd readahead prefetching.
122
123  Returns:
124    A bool indicates whether the disabling is done successfully or not.
125  """
126  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
127                                       'iorapd_readahead_disable', [])
128  return passed
129
130def enable_iorapd_perfetto() -> bool:
131  """
132  Enable Perfetto. Subsequent launches of an application will record a perfetto
133  trace protobuf.
134
135  Returns:
136    A bool indicates whether the enabling is done successfully or not.
137  """
138  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
139                                       'iorapd_perfetto_enable', [])
140  return passed
141
142def disable_iorapd_perfetto() -> bool:
143  """
144  Disable Perfetto. Subsequent launches of applications will no longer record
145  perfetto trace protobufs.
146
147  Returns:
148    A bool indicates whether the disabling is done successfully or not.
149  """
150  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
151                                       'iorapd_perfetto_disable', [])
152  return passed
153
154def start_iorapd() -> bool:
155  """
156  Starts iorapd.
157
158  Returns:
159    A bool indicates whether the starting is done successfully or not.
160  """
161  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
162                                       'iorapd_start', [])
163  return passed
164
165def stop_iorapd() -> bool:
166  """
167  Stops iorapd.
168
169  Returns:
170    A bool indicates whether the stopping is done successfully or not.
171  """
172  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
173                                       'iorapd_stop', [])
174  return passed
175
176