What I’ve learned from wa output
Workload-automation is a great tool for benchmark automation, it utilizes tools in sdk and android system, including aapt, pm, am etc through devlib, this post will try to show how these tools are used in devlib.
aapt
aapt
is an android sdk tool running on host computer, it was used for dump apk
information such as version, activity and so forth, with dump badging
, here
I take KISS launcher for example:
$ aapt dump badging fr.neamar.kiss_151.apk
package: name='fr.neamar.kiss' versionCode='151' versionName='3.7.11' compileSdkVersion='28' compileSdkVersionCodename='9'
sdkVersion:'15'
targetSdkVersion:'28'
uses-permission: name='android.permission.READ_CONTACTS'
uses-permission: name='android.permission.CALL_PHONE'
uses-permission: name='android.permission.READ_PHONE_STATE'
uses-permission: name='android.permission.EXPAND_STATUS_BAR'
uses-permission: name='android.permission.REQUEST_DELETE_PACKAGES'
application-label:'KISS launcher'
... ...
application-label-se:'KISS launcher'
application-label-sk:'KISS launcher'
application-label-sr:'КИС покретач'
application-label-sv:'Kiss launcher'
application-label-tr:'KISS başlatıcı'
application-label-uk:'KISS Запускач'
application-label-zh-CN:'KISS 启动器'
application-label-zh-TW:'KISS 桌面'
application-icon-160:'res/drawable-mdpi-v4/ic_launcher.png'
application-icon-240:'res/drawable-hdpi-v4/ic_launcher.png'
application-icon-320:'res/drawable-xhdpi-v4/ic_launcher.png'
application-icon-480:'res/drawable-xxhdpi-v4/ic_launcher.png'
application: label='KISS launcher' icon='res/drawable-mdpi-v4/ic_launcher.png'
launchable-activity: name='fr.neamar.kiss.MainActivity' label='KISS launcher' icon=''
feature-group: label=''
uses-feature-not-required: name='android.hardware.bluetooth'
uses-feature-not-required: name='android.hardware.nfc'
uses-feature-not-required: name='android.hardware.telephony'
uses-feature-not-required: name='android.hardware.wifi'
uses-feature: name='android.hardware.faketouch'
uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps'
provides-component:'launcher'
main
other-activities
other-receivers
other-services
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--' 'ar' 'ast' 'az' 'bg' 'ca' 'cs' 'de' 'el' 'eo' 'es' 'et' 'fa' 'fi' 'fr' 'gl' 'hr' 'hu' 'in' 'it' 'ja' 'lt' 'nb' 'nl' 'pl' 'pt-BR' 'pt-PT' 'ro' 'ru' 'se' 'sk' 'sr' 'sv' 'tr' 'uk' 'zh-CN' 'zh-TW'
densities: '160' '240' '320' '480'
From the output we can get:
package: name='fr.neamar.kiss'
versionCode='151'
versionName='3.7.11'
launchable-activity: name='fr.neamar.kiss.MainActivity'
dump permssions:
$ aapt dump permissions fr.neamar.kiss_151.apk
package: fr.neamar.kiss
permission: com.android.launcher.permission.INSTALL_SHORTCUT
permission: com.android.launcher.permission.UNINSTALL_SHORTCUT
uses-permission: name='android.permission.READ_CONTACTS'
uses-permission: name='android.permission.CALL_PHONE'
uses-permission: name='android.permission.READ_PHONE_STATE'
uses-permission: name='android.permission.EXPAND_STATUS_BAR'
uses-permission: name='android.permission.REQUEST_DELETE_PACKAGES'
dump apk versionName:
aapt dump badging DeskClock.apk | sed -n "s/.*versionName='\([^']*\).*/\1/p"
aapt can do more than this, do aapt without subcommand to show full help.
settings
wa use settings
to change screen settings to make sure the system will not be
locked to prevent further automation task:
settings put system screen_brightness_mode 0
settings put system screen_brightness 127
A lot of settings can be changed with this command, here is the full list of settings supported by android:
# system namespace
rpi3:/ # settings list system
accelerometer_rotation=0
alarm_alert=content://media/internal/audio/media/14
alarm_alert_set=1
dim_screen=1
dtmf_tone=1
dtmf_tone_type=0
egg_mode=1559779571913
haptic_feedback_enabled=1
hearing_aid=0
lockscreen_sounds_enabled=1
mode_ringer_streams_affected=166
mute_streams_affected=46
notification_light_pulse=1
notification_sound=content://media/internal/audio/media/33
notification_sound_set=1
pointer_speed=0
ringtone=content://media/internal/audio/media/113
ringtone_set=1
screen_brightness=255
screen_brightness_mode=0
screen_off_timeout=60000
show_processes=1
sound_effects_enabled=1
transition_animation_scale=1.0
tty_mode=0
vibrate_when_ringing=0
volume_alarm=6
volume_bluetooth_sco=7
volume_music=5
volume_music_usb_headset=3
volume_notification=5
volume_ring=5
volume_system=7
volume_voice=4
window_animation_scale=1.0
# global namespace
rpi3:/ # settings list global
add_users_when_locked=0
airplane_mode_on=0
airplane_mode_radios=cell,bluetooth,wifi,nfc,wimax
airplane_mode_toggleable_radios=bluetooth,wifi,nfc
assisted_gps_enabled=1
audio_safe_volume_state=3
auto_time=1
auto_time_zone=1
bluetooth_disabled_profiles=0
bluetooth_on=0
boot_count=5
call_auto_retry=0
captive_portal_detection_enabled=0
car_dock_sound=/system/media/audio/ui/Dock.ogg
car_undock_sound=/system/media/audio/ui/Undock.ogg
cdma_cell_broadcast_sms=1
data_roaming=0
database_creation_buildid=OPM7.181205.001
default_install_location=0
default_restrict_background_data=0
desk_dock_sound=/system/media/audio/ui/Dock.ogg
desk_undock_sound=/system/media/audio/ui/Undock.ogg
development_settings_enabled=1
device_name=Raspberry Pi 3
device_provisioned=1
dock_audio_media_enabled=1
dock_sounds_enabled=0
dock_sounds_enabled_when_accessbility=0
emergency_affordance_needed=0
emergency_tone=0
heads_up_notifications_enabled=1
lock_sound=/system/media/audio/ui/Lock.ogg
low_battery_sound=/system/media/audio/ui/LowBattery.ogg
low_battery_sound_timeout=0
mobile_data=1
mode_ringer=2
netstats_enabled=1
network_recommendations_enabled=0
package_verifier_enable=1
power_sounds_enabled=1
preferred_network_mode=0
set_install_location=0
stay_on_while_plugged_in=1
subscription_mode=0
theater_mode_on=0
trusted_sound=/system/media/audio/ui/Trusted.ogg
unlock_sound=/system/media/audio/ui/Unlock.ogg
usb_mass_storage_enabled=1
volte_vt_enabled=1
webview_provider=com.android.webview
wifi_display_on=0
wifi_max_dhcp_retry_count=9
wifi_networks_available_notification_on=1
wifi_on=0
wifi_scan_always_enabled=0
wifi_sleep_policy=2
wifi_wakeup_available=1
wifi_wakeup_enabled=1
wireless_charging_started_sound=/system/media/audio/ui/WirelessChargingStarted.ogg
zen_mode=0
zen_mode_config_etag=2104396556
# secure namespace
rpi3:/ # settings list secure
accessibility_display_magnification_enabled=0
accessibility_display_magnification_scale=2.0
accessibility_enabled=0
android_id=a214d407341fa48
autofill_service=
backup_enabled=null
backup_transport=com.google.android.gms/.backup.BackupTransportService
default_input_method=com.android.inputmethod.latin/.LatinIME
double_tap_to_wake=1
enabled_input_methods=com.android.inputmethod.latin/.LatinIME
enabled_notification_assistant=
enabled_notification_listeners=
enabled_notification_policy_access_packages=
immersive_mode_confirmations=
input_methods_subtype_history=com.android.inputmethod.latin/.LatinIME;-921088104
install_non_market_apps=1
location_providers_allowed=gps
lock_screen_allow_private_notifications=1
lock_screen_owner_info_enabled=0
lock_screen_show_notifications=1
lockscreen.disabled=1
long_press_timeout=400
mock_location=0
mount_play_not_snd=1
mount_ums_autostart=0
mount_ums_notify_enabled=1
mount_ums_prompt=1
multi_press_timeout=300
overview_last_stack_active_time=1559779689197
screensaver_activate_on_dock=1
screensaver_activate_on_sleep=0
screensaver_components=com.google.android.deskclock/com.android.deskclock.Screensaver
screensaver_default_component=com.google.android.deskclock/com.android.deskclock.Screensaver
screensaver_enabled=1
selected_input_method_subtype=-921088104
selected_spell_checker=com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService
show_ime_with_hard_keyboard=0
show_note_about_notification_hiding=0
sleep_timeout=-1
snoozed_schedule_condition_provider=
speak_password=1
sync_parent_sounds=0
sysui_tuner_version=1
touch_exploration_enabled=0
trust_agents_initialized=1
unknown_sources_default_reversed=1
user_setup_complete=1
wake_gesture_enabled=1
pm
We get enough information about the apk with aapt, now pm
walks onto the stage,
pm stands for package manager, the most frequently used commands are pm install/
uninstall
pm disable/enable
, the following commands are used in devlib:
# List all installed packages
pm list packages
# Show apk file related to a package
pm list packages -f fr.neamar.kiss
# Clear all data associated with a package
pm clear fr.neamar.kiss
# Grant permissions declared in AndroidManifest.xml
pm grant fr.neamar.kiss android.permission.READ_CONTACTS
Be aware that pm list was moved as stated in the help, use cmd instead:
rpi3:/ # cmd package list packages -f fr.neamar.kiss
In devlib, pm grant
was used in grant_package_permission function:
def grant_package_permission(self, package, permission):
try:
return self.execute('pm grant {} {}'.format(quote(package), quote(permission)))
except TargetStableError as e:
if 'is not a changeable permission type' in e.message:
pass # Ignore if unchangeable
elif 'Unknown permission' in e.message:
pass # Ignore if unknown
elif 'has not requested permission' in e.message:
pass # Ignore if not requested
elif 'Operation not allowed' in e.message:
pass # Ignore if not allowed
else:
raise
We see the error messages were ignored, but why failed, I’m gonna talk a little
more about this, because I met this error message few days ago, I got is not a
changeable permission type
when I do pm grant on permission REQUEST_DELETE_PACKAGES:
rpi3:/ # pm grant fr.neamar.kiss android.permission.REQUEST_DELETE_PACKAGES
Operation not allowed: java.lang.SecurityException: Permission android.permission.REQUEST_DELETE_PACKAGES is not a changeable permission type
Same thing happens when grant permissions to REQUEST_DELETE_PACKAGES, EXPAND_STATUS_BAR
, these permissions are defined in frameworks/base/core/res/AndroidManifest.xml,
all of them set protectionLevel to normal
:
<!-- Allows an application to expand or collapse the status bar.
<p>Protection level: normal
-->
<permission android:name="android.permission.EXPAND_STATUS_BAR"
android:label="@string/permlab_expandStatusBar"
android:description="@string/permdesc_expandStatusBar"
android:protectionLevel="normal" />
<!-- Allows an application to request deleting packages. Apps
targeting APIs greater than 25 must hold this permission in
order to use {@link android.content.Intent#ACTION_UNINSTALL_PACKAGE}.
<p>Protection level: normal
-->
<permission android:name="android.permission.REQUEST_DELETE_PACKAGES"
android:label="@string/permlab_requestDeletePackages"
android:description="@string/permdesc_requestDeletePackages"
android:protectionLevel="normal" />
Official document saids permissions with normal protectionLevel will be granted at installation:
Other permissions INSTALL_SHORTCUT, UNINSTALL_SHORTCUT set protectionLevel to normal too in its AndroidManifest.xml.
<permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal" />
<permission
android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal" />
See full list of pm commands in help:
rpi3:/ # pm
usage: pm path [--user USER_ID] PACKAGE
pm dump PACKAGE
pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]
pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]
[--install-location 0/1/2]
[--force-uuid internal|UUID]
pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]
pm install-commit SESSION_ID
pm install-abandon SESSION_ID
pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE
pm set-installer PACKAGE INSTALLER
pm move-package PACKAGE [internal|UUID]
pm move-primary-storage [internal|UUID]
pm clear [--user USER_ID] PACKAGE
pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT
pm set-user-restriction [--user USER_ID] RESTRICTION VALUE
pm hide [--user USER_ID] PACKAGE_OR_COMPONENT
pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT
pm grant [--user USER_ID] PACKAGE PERMISSION
pm revoke [--user USER_ID] PACKAGE PERMISSION
pm reset-permissions
pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
pm get-app-link [--user USER_ID] PACKAGE
pm set-install-location [0/auto] [1/internal] [2/external]
pm get-install-location
pm set-permission-enforced PERMISSION [true|false]
pm trim-caches DESIRED_FREE_SPACE [internal|UUID]
pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME
pm remove-user USER_ID
pm get-max-users
NOTE: 'pm list' commands have moved! Run 'adb shell cmd package'
to display the new commands.
pm path: print the path to the .apk of the given PACKAGE.
pm dump: print system state associated with the given PACKAGE.
pm install: install a single legacy package
pm install-create: create an install session
-l: forward lock application
-r: replace existing application
-t: allow test packages
-i: specify the installer package name
-s: install application on sdcard
-f: install application on internal flash
-d: allow version code downgrade (debuggable packages only)
-p: partial application install
-g: grant all runtime permissions
-S: size in bytes of entire session
pm install-write: write a package into existing session; path may
be '-' to read from stdin
-S: size in bytes of package, required for stdin
pm install-commit: perform install of fully staged session
pm install-abandon: abandon session
pm set-installer: set installer package name
pm uninstall: removes a package from the system. Options:
-k: keep the data and cache directories around after package removal.
pm clear: deletes all data associated with a package.
pm enable, disable, disable-user, disable-until-used, default-state:
these commands change the enabled state of a given package or
component (written as "package/class").
pm grant, revoke: these commands either grant or revoke permissions
to apps. The permissions must be declared as used in the app's
manifest, be runtime permissions (protection level dangerous),
and the app targeting SDK greater than Lollipop MR1.
pm reset-permissions: revert all runtime permissions to their default state.
pm get-install-location: returns the current install location.
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media
pm set-install-location: changes the default install location.
NOTE: this is only intended for debugging; using this can cause
applications to break and other undersireable behavior.
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media
pm trim-caches: trim cache files to reach the given free space.
pm create-user: create a new user with the given USER_NAME,
printing the new user identifier of the user.
pm remove-user: remove the user with the given USER_IDENTIFIER,
deleting all data associated with that user
am
TODO
cmd
TODO
dumpsys
dumpsys input
dumpsys window displays
dumpsys package com.android.calculator2
dumpsys gfxinfo --list framestats
dumpsys SurfaceFlinger --latency {}
dumpsys SurfaceFlinger --latency-clear
dumpsys gfxinfo {} framestats
dumpsys power
The above commands are used in devlib, let’s explain them one by one.
dumpsys input
devlib use this command to determine the device orientation state, which was shown in Input Reader State section:
Input Reader State:
Device -1: Virtual
Generation: 2
IsExternal: false
HasMic: false
Sources: 0x00000301
KeyboardType: 2
Keyboard Input Mapper:
Parameters:
HasAssociatedDisplay: true
OrientationAware: true
HandlesKeyRepeat: false
KeyboardType: 2
Orientation: 0
KeyDowns: 0 keys currently down
MetaState: 0x0
DownTime: 0
Device 1: Logitech USB Receiver
Generation: 17
IsExternal: true
HasMic: false
Sources: 0x01002313
KeyboardType: 1
Motion Ranges:
X: source=0x00002002, min=0.000, max=799.000, flat=0.000, fuzz=0.000, resolution=0.000
Y: source=0x00002002, min=0.000, max=479.000, flat=0.000, fuzz=0.000, resolution=0.000
PRESSURE: source=0x00002002, min=0.000, max=1.000, flat=0.000, fuzz=0.000, resolution=0.000
VSCROLL: source=0x00002002, min=-1.000, max=1.000, flat=0.000, fuzz=0.000, resolution=0.000
HSCROLL: source=0x00002002, min=-1.000, max=1.000, flat=0.000, fuzz=0.000, resolution=0.000
GENERIC_1: source=0x01000010, min=0.000, max=1.000, flat=0.000, fuzz=0.000, resolution=0.000
Keyboard Input Mapper:
Parameters:
HasAssociatedDisplay: false
OrientationAware: false
HandlesKeyRepeat: false
KeyboardType: 1
Orientation: 0
KeyDowns: 0 keys currently down
MetaState: 0x0
DownTime: 0
Cursor Input Mapper:
Parameters:
HasAssociatedDisplay: true
Mode: pointer
OrientationAware: false
XScale: 1.000
YScale: 1.000
XPrecision: 1.000
YPrecision: 1.000
HaveVWheel: true
HaveHWheel: true
VWheelScale: 1.000
HWheelScale: 1.000
Orientation: 0
ButtonState: 0x00000000
Down: false
DownTime: 10160038720000
Joystick Input Mapper:
Axes:
GENERIC_1: min=0.00000, max=1.00000, flat=0.00000, fuzz=0.00000, resolution=0.00000
scale=0.00154, offset=0.00000, highScale=0.00154, highOffset=0.00000
rawAxis=32, rawMin=1, rawMax=652, rawFlat=0, rawFuzz=0, rawResolution=0
Device 2: Logitech USB Receiver
Generation: 6
IsExternal: true
HasMic: false
Sources: 0x00000101
KeyboardType: 2
Keyboard Input Mapper:
Parameters:
HasAssociatedDisplay: false
OrientationAware: false
HandlesKeyRepeat: false
KeyboardType: 2
Orientation: 0
KeyDowns: 2 keys currently down
MetaState: 0x3012
DownTime: 42598105653000
In frameworks/native/libs/ui/include/ui/DisplayInfo.h, four orientations are defined:
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
enum {
DISPLAY_ORIENTATION_0 = 0,
DISPLAY_ORIENTATION_90 = 1,
DISPLAY_ORIENTATION_180 = 2,
DISPLAY_ORIENTATION_270 = 3
};
In this case the orientation is 0, which means horizontal:
Orientation: 0
Orientation value can be set with settings put system user_rotation 1
dumpsys package package_name
To get package information such as versionName, requested permsstion etc,
dumpsys package
can be used, below is the sample output of kisslauncher package
info:
# dumpsys package fr.neamar.kiss
... ...
Packages:
Package [fr.neamar.kiss] (b544279):
userId=10070
pkg=Package{1b75bbe fr.neamar.kiss}
codePath=/data/app/fr.neamar.kiss-l064iovAlwg8FN566fRPsA==
resourcePath=/data/app/fr.neamar.kiss-l064iovAlwg8FN566fRPsA==
legacyNativeLibraryDir=/data/app/fr.neamar.kiss-l064iovAlwg8FN566fRPsA==/lib
primaryCpuAbi=null
secondaryCpuAbi=null
versionCode=151 minSdk=15 targetSdk=28
versionName=3.7.11
splits=[base]
apkSigningVersion=1
applicationInfo=ApplicationInfo{52bf340 fr.neamar.kiss}
flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
privateFlags=[ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE ]
dataDir=/data/user/0/fr.neamar.kiss
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
timeStamp=1969-12-31 20:10:26
firstInstallTime=1969-12-31 20:10:27
lastUpdateTime=1969-12-31 20:10:27
signatures=PackageSignatures{bfa241f [555063de]}
installPermissionsFixed=true installStatus=1
pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
requested permissions:
android.permission.READ_CONTACTS
android.permission.CALL_PHONE
android.permission.READ_PHONE_STATE
android.permission.EXPAND_STATUS_BAR
android.permission.REQUEST_DELETE_PACKAGES
install permissions:
android.permission.EXPAND_STATUS_BAR: granted=true
android.permission.REQUEST_DELETE_PACKAGES: granted=true
User 0: ceDataInode=-4294965595 installed=true hidden=false suspended=false stopped=true notLaunched=true enabled=0 instant=false virtual=false
runtime permissions:
android.permission.READ_CONTACTS: granted=true
... ...
dumpsys window displays
The following is part of the dumpsys window displays
output, devlib can get
android screen resolution by searching with regex expression:
WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)
Display: mDisplayId=0
init=800x480 160dpi cur=800x480 app=752x480 rng=480x456-752x728
deferred=false mLayoutNeeded=false mTouchExcludeRegion=SkRegion((0,0,800,480))
dumpsys supported services may vary depending on the Android version the device
use, to get a complete list of supported services with dumpsys -l
:
Currently running services:
DockObserver
SurfaceFlinger
accessibility
account
activity
alarm
android.security.keystore
android.service.gatekeeper.IGateKeeperService
appops
appwidget
audio
autofill
backup
battery
batteryproperties
batterystats
bluetooth_manager
carrier_config
clipboard
commontime_management
companiondevice
connectivity
connmetrics
consumer_ir
content
contexthub
country_detector
cpuinfo
dbinfo
device_identifiers
device_policy
deviceidle
devicestoragemonitor
diskstats
display
dreams
drm.drmManager
dropbox
ethernet
gfxinfo
gpu
graphicsstats
hardware_properties
imms
input
input_method
installd
iphonesubinfo
isms
isub
jobscheduler
launcherapps
lineageaudio
lineagehardware
lineagelivedisplay
lineageperformance
lineagestyle
lineagetrust
lineageweather
location
lock_settings
media.audio_flinger
media.audio_policy
media.camera
media.camera.proxy
media.codec
media.drm
media.extractor
media.metrics
media.player
media.resource_manager
media.sound_trigger_hw
media_projection
media_resource_monitor
media_router
media_session
meminfo
mount
netd
netd_listener
netpolicy
netstats
network_management
network_score
network_time_update_service
notification
otadexopt
overlay
package
package_native
permission
phone
pinner
power
print
processinfo
procstats
profile
recovery
restrictions
rttmanager
scheduling_policy
search
sec_key_att_app_id_provider
sensorservice
serial
servicediscovery
settings
shortcut
simphonebook
sip
soundtrigger
statusbar
storaged
storagestats
telecom
telephony.registry
textservices
thermalservice
trust
uimode
updatelock
usagestats
usb
user
vibrator
voiceinteraction
vrmanager
wallpaper
webviewupdate
wifi
wificond
wifiscanner
window