1 # /* vim: set ai ts=4 ft=sh: */ 2 # 3 # Copyright 2011, 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 18 _adb() { 19 unset -v have 20 type $1 &> /dev/null && have="yes" 21 22 if [ "$have" != "yes" ]; then 23 return 24 fi 25 26 local where i cur serial 27 COMPREPLY=() 28 29 serial="${ANDROID_SERIAL:-none}" 30 where=OPTIONS 31 for ((i=1; i <= COMP_CWORD; i++)); do 32 cur="${COMP_WORDS[i]}" 33 case "${cur}" in 34 -s) 35 where=OPT_SERIAL 36 ;; 37 -p) 38 where=OPT_PATH 39 ;; 40 -*) 41 where=OPTIONS 42 ;; 43 *) 44 if [[ $where == OPT_SERIAL ]]; then 45 where=OPT_SERIAL_ARG 46 elif [[ $where == OPT_SERIAL_ARG ]]; then 47 serial=${cur} 48 where=OPTIONS 49 else 50 where=COMMAND 51 break 52 fi 53 ;; 54 esac 55 done 56 57 if [[ $where == COMMAND && $i -ge $COMP_CWORD ]]; then 58 where=OPTIONS 59 fi 60 61 OPTIONS="-d -e -s -p" 62 COMMAND="devices connect disconnect push pull sync shell emu logcat lolcat forward jdwp install uninstall bugreport help version start-server kill-server get-state get-serialno status-window remount reboot reboot-bootloader root usb tcpip disable-verity" 63 64 case $where in 65 OPTIONS|OPT_SERIAL|OPT_PATH) 66 COMPREPLY=( $(compgen -W "$OPTIONS $COMMAND" -- "$cur") ) 67 ;; 68 OPT_SERIAL_ARG) 69 local devices=$(command adb devices 2> /dev/null | grep -v "List of devices" | awk '{ print $1 }') 70 COMPREPLY=( $(compgen -W "${devices}" -- ${cur}) ) 71 ;; 72 COMMAND) 73 if [[ $i -eq $COMP_CWORD ]]; then 74 COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") ) 75 else 76 i=$((i+1)) 77 case "${cur}" in 78 install) 79 _adb_cmd_install "$serial" $i 80 ;; 81 sideload) 82 _adb_cmd_sideload "$serial" $i 83 ;; 84 pull) 85 _adb_cmd_pull "$serial" $i 86 ;; 87 push) 88 _adb_cmd_push "$serial" $i 89 ;; 90 reboot) 91 if [[ $COMP_CWORD == $i ]]; then 92 args="bootloader recovery" 93 COMPREPLY=( $(compgen -W "${args}" -- "${COMP_WORDS[i]}") ) 94 fi 95 ;; 96 shell) 97 _adb_cmd_shell "$serial" $i 98 ;; 99 uninstall) 100 _adb_cmd_uninstall "$serial" $i 101 ;; 102 esac 103 fi 104 ;; 105 esac 106 107 return 0 108 } 109 110 _adb_cmd_install() { 111 local serial i cur where 112 113 serial=$1 114 i=$2 115 116 where=OPTIONS 117 for ((; i <= COMP_CWORD; i++)); do 118 cur="${COMP_WORDS[i]}" 119 case "${cur}" in 120 -*) 121 where=OPTIONS 122 ;; 123 *) 124 where=FILE 125 break 126 ;; 127 esac 128 done 129 130 cur="${COMP_WORDS[COMP_CWORD]}" 131 if [[ $where == OPTIONS ]]; then 132 COMPREPLY=( $(compgen -W "-d -l -r -s" -- "${cur}") ) 133 return 134 fi 135 136 _adb_util_complete_local_file "${cur}" '!*.apk' 137 } 138 139 _adb_cmd_sideload() { 140 local serial i cur 141 142 serial=$1 143 i=$2 144 145 cur="${COMP_WORDS[COMP_CWORD]}" 146 147 _adb_util_complete_local_file "${cur}" '!*.zip' 148 } 149 150 _adb_cmd_push() { 151 local serial IFS=$'\n' i cur 152 153 serial=$1 154 i=$2 155 156 cur="${COMP_WORDS[COMP_CWORD]}" 157 158 if [[ $COMP_CWORD == $i ]]; then 159 _adb_util_complete_local_file "${cur}" 160 elif [[ $COMP_CWORD == $(($i+1)) ]]; then 161 if [ "${cur}" == "" ]; then 162 cur="/" 163 fi 164 _adb_util_list_files $serial "${cur}" 165 fi 166 } 167 168 _adb_cmd_pull() { 169 local serial IFS=$'\n' i cur 170 171 serial=$1 172 i=$2 173 174 cur="${COMP_WORDS[COMP_CWORD]}" 175 176 if [[ $COMP_CWORD == $i ]]; then 177 if [ "${cur}" == "" ]; then 178 cur="/" 179 fi 180 _adb_util_list_files $serial "${cur}" 181 elif [[ $COMP_CWORD == $(($i+1)) ]]; then 182 _adb_util_complete_local_file "${cur}" 183 fi 184 } 185 186 _adb_cmd_shell() { 187 local serial IFS=$'\n' i cur 188 local -a args 189 190 serial=$1 191 i=$2 192 193 cur="${COMP_WORDS[i]}" 194 if [ "$serial" != "none" ]; then 195 args=(-s $serial) 196 fi 197 198 if [[ $i -eq $COMP_CWORD && ${cur:0:1} != "/" ]]; then 199 paths=$(command adb ${args[@]} shell echo '$'PATH 2> /dev/null | tr -d '\r' | tr : '\n') 200 COMMAND=$(command adb ${args[@]} shell ls $paths '2>' /dev/null | tr -d '\r' | { 201 while read -r tmp; do 202 command=${tmp##*/} 203 printf '%s\n' "$command" 204 done 205 }) 206 COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur") ) 207 return 0 208 fi 209 210 i=$((i+1)) 211 case "$cur" in 212 ls) 213 _adb_shell_ls $serial $i 214 ;; 215 /*) 216 _adb_util_list_files $serial "$cur" 217 ;; 218 *) 219 COMPREPLY=( ) 220 ;; 221 esac 222 223 return 0 224 } 225 226 _adb_cmd_uninstall() { 227 local serial i where cur packages 228 229 serial=$1 230 i=$2 231 if [ "$serial" != "none" ]; then 232 args=(-s $serial) 233 fi 234 235 where=OPTIONS 236 for ((; i <= COMP_CWORD; i++)); do 237 cur="${COMP_WORDS[i]}" 238 case "${cur}" in 239 -*) 240 where=OPTIONS 241 ;; 242 *) 243 where=FILE 244 break 245 ;; 246 esac 247 done 248 249 cur="${COMP_WORDS[COMP_CWORD]}" 250 if [[ $where == OPTIONS ]]; then 251 COMPREPLY=( $(compgen -W "-k" -- "${cur}") ) 252 fi 253 254 packages="$( 255 command adb ${args[@]} shell pm list packages '2>' /dev/null 2> /dev/null | tr -d '\r' | { 256 while read -r tmp; do 257 local package=${tmp#package:} 258 echo -n "${package} " 259 done 260 } 261 )" 262 263 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${packages}" -- "${cur}") ) 264 } 265 266 _adb_shell_ls() { 267 local serial i cur file 268 local -a args 269 270 serial=$1 271 i=$2 272 if [ "$serial" != "none" ]; then 273 args=(-s $serial) 274 fi 275 276 where=OPTIONS 277 for ((; i <= COMP_CWORD; i++)); do 278 cur="${COMP_WORDS[i]}" 279 case "${cur}" in 280 -*) 281 where=OPTIONS 282 ;; 283 *) 284 where=FILE 285 break 286 ;; 287 esac 288 done 289 290 file="${COMP_WORDS[COMP_CWORD]}" 291 if [[ ${file} == "" ]]; then 292 file="/" 293 fi 294 295 case $where in 296 OPTIONS) 297 COMPREPLY=( $(compgen -W "$OPTIONS" -- "$cur") ) 298 _adb_util_list_files $serial "$file" 299 ;; 300 FILE) 301 _adb_util_list_files $serial "$file" 302 ;; 303 esac 304 305 return 0 306 } 307 308 _adb_util_list_files() { 309 local serial dir IFS=$'\n' 310 local -a toks 311 local -a args 312 313 serial="$1" 314 file="$2" 315 316 if [ "$serial" != "none" ]; then 317 args=(-s $serial) 318 fi 319 320 toks=( ${toks[@]-} $( 321 command adb ${args[@]} shell ls -dF ${file}"*" '2>' /dev/null 2> /dev/null | tr -d '\r' | { 322 while read -r tmp; do 323 filetype=${tmp%% *} 324 filename=${tmp:${#filetype}+1} 325 if [[ ${filetype:${#filetype}-1:1} == d ]]; then 326 printf '%s/\n' "$filename" 327 else 328 printf '%s\n' "$filename" 329 fi 330 done 331 } 332 )) 333 334 # Since we're probably doing file completion here, don't add a space after. 335 if [[ $(type -t compopt) = "builtin" ]]; then 336 compopt -o nospace 337 fi 338 339 COMPREPLY=( ${COMPREPLY[@]:-} "${toks[@]}" ) 340 } 341 342 _adb_util_complete_local_file() 343 { 344 local file xspec i j IFS=$'\n' 345 local -a dirs files 346 347 file=$1 348 xspec=$2 349 350 # Since we're probably doing file completion here, don't add a space after. 351 if [[ $(type -t compopt) = "builtin" ]]; then 352 compopt -o plusdirs 353 if [[ "${xspec}" == "" ]]; then 354 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") ) 355 else 356 compopt +o filenames 357 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") ) 358 fi 359 else 360 # Work-around for shells with no compopt 361 362 dirs=( $(compgen -d -- "${cur}" ) ) 363 364 if [[ "${xspec}" == "" ]]; then 365 files=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}") ) 366 else 367 files=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}") ) 368 fi 369 370 COMPREPLY=( $( 371 for i in "${files[@]}"; do 372 local skip= 373 for j in "${dirs[@]}"; do 374 if [[ $i == $j ]]; then 375 skip=1 376 break 377 fi 378 done 379 [[ -n $skip ]] || printf "%s\n" "$i" 380 done 381 )) 382 383 COMPREPLY=( ${COMPREPLY[@]:-} $( 384 for i in "${dirs[@]}"; do 385 printf "%s/\n" "$i" 386 done 387 )) 388 fi 389 } 390 391 392 if [[ $(type -t compopt) = "builtin" ]]; then 393 complete -F _adb adb 394 else 395 complete -o nospace -F _adb adb 396 fi 397