June 5, 2017

What happens behind the scenes as Appium installs and launches an Android app? Examining and footnoting a log file.

This is part seven of of a seven-part blog series. Care to go back to the beginning?

Have you ever wondered what is happening behind-the-scenes as Appium launches an app? Well, there is one way to find out...

Today, we will be taking a look at the log files captured in the Appium console, generated after I launch the APIDemos-debug.apk Android app, with the help of Appium, onto an Android emulator.

... Actually, this blog article wasn't written in a day. It took more than a few weekends to thoroughly research everything... and I do mean everything!

There are possible errors or questions on the inner workings on Appium, with insightful statements such as ... "Huh? What's this?" ... They are highlighted in red.

Is there anything I am wrong about? Please let me know! I am a complete novice when it comes to Appium (although, I have been hideously busy).  I only started learning it in March of 2017. The reason I am blogging about this is because I actually want you to comment if I am completely off-base, or if I am error about the inner workings of Appium or the world of Android development.




What is an APK?

  • APK stands for Android Application Package

"Android Package Kit (APK) is the package file format used by the Android operating system for distribution and installation of mobile apps and middleware [...] To make an APK file, a program for Android is first compiled, and then all of its parts are packaged into one file. An APK file contains all of that program's code [...] resources, assets, certificates, and manifest file. As is the case with many file formats, APK files can have any name needed, provided that the file name ends in ".apk" [...] APK files are a type of archive file, specifically in zip format packages based on the JAR file format, with .apk as the filename extension. The MIME type associated with APK files is application/vnd.android.package-archive.]" - Wikipedia, Android Package Kit. 

When you first start the Appium console, Appium patiently waits in the background...

[Appium] Welcome to Appium v1.6.4
[Appium] Appium REST http interface listener started on 0.0.0.0:4723


... but when you feed a set of Desired Capabilites to it, and Appium finds an emulator matching them, a flurry of activity happens as it installs the app on the emulator. It will use a series of Android command line tools to inspect the emulator, find Android application packages that are running, and inspect these APKs, check if there are any special settings, and Appium will launch them.

How does the Appium Server start?
It works the similar way as common ChromeDriverInternetExplorerDriver of Selenium project or PhantomJSDriver. They use subclasses of the DriverService.
This feature provides abilities and options of the starting of a local Appium node server. End users still able to open apps as usual. - Appium Java Client Docs, The Starting of an App Using Appium Node Server.





Let's review what is happening, section by section...

What Are We Feeding That Thing?

For this example, we are sending to Appium the code:

 final String URL_STRING = "http://127.0.0.1:4723/wd/hub";
 URL url = new URL(URL_STRING);

 File app = new File("ApiDemos-debug.apk");  
 DesiredCapabilities caps = new DesiredCapabilities();  
 caps.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator-5554");  
 caps.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());  
 caps.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);  
 AndroidDriver driver = new AndroidDriver(url, caps);  
  • Appium Server is listening on 127.0.0.1.
  • The Android emulator is on emulator-555-4, and if we use adb devices, we will see it in the list
  • The code above sets a String constant URL_STRING and a url variable the value of our old friend localhost, the Home IP, 127.0.0.1. 
  • /wd/hub is our old friend, the Selenium Hub, part of the Selenium Grid. 
  • When a new instance of AndroidDriver is created, we are setting it to the Selenium Hub and Appium Server listening in at 127.0.0.1, and passing along the DesiredCapabilities. Appium will be connected to the Selenium Grid. 

"What is Selenium-Grid?

"Selenium-Grid allows you run your tests on different machines against different browsers in parallel. That is, running multiple tests at the same time against different machines running different browsers and operating systems. Essentially, Selenium-Grid support distributed test execution. It allows for running your tests in a distributed test execution environment.

"When to Use It

"Generally speaking, there are two reasons why you might want to use Selenium-Grid.

  • "To run your tests against multiple browsers, multiple versions of browser, and browsers running on different operating systems.
  • "To reduce the time it takes for the test suite to complete a test pass.
"Selenium-Grid is used to speed up the execution of a test pass by using multiple machines to run tests in parallel". - Selenium HQ Docs, Selenium Grid

[HTTP] --> POST /wd/hub/session {"desiredCapabilities":{"app":"/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk","platformName":"Android","deviceName":"emulator-5554"}}
  • The desired capabilities are being posted via HTTP, to the Selenium Grid that Appium is connected to, much as if you were submitting a web form, POST-ing it to another service. 

[MJSONWP] Calling AppiumDriver.createSession() with args: [{"app":"/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk","platformName":"Android","deviceName":"emulator-5554"},null,null,null,null]


  • Next, we have the Mobile JSON Wire Protocol calling the Appium Driver Method, create session with the arguments we passed into the DesiredCapabilites: where the app is located (the absolute path), the platform name (Android), and the deviceName (emulator-5554). 
  • See official documentation on the JSON Wire Protocol.
  • See the Mobile JSON Wire errors that can be thrown in the Appium Base Driver on Appium's GitHub site. 
The Mobile JSON Wire Protocolhttps://youtu.be/wjvAh4yjwtI



[BaseDriver] Event 'newSessionRequested' logged at 1495296256238 (12:04:16 GMT-0400 (EDT))

  • The Appium Base Driver registers when the new session was requested in Greenwich Mean Time (-400) since I am in Quincy, MA when the request was made. Eastern Daylight Time.
  • What is the Appium base driver? 
"This is the parent class that all appium drivers inherit from. Appium drivers themselves can either be started from the command line as standalone appium servers, or can be included by another module (appium) which then proxies commands to the appropriate driver based on Desired Capabilities.
"An appium driver is a module which processes Mobile Json Wire Protocol commands and controls a device accordingly. The commands can either come in over HTTP as json api requests, or they can be passed to the driver object programmatically as already-parsed json object (without the HTTP headers and junk).
"The appium Base driver already includes the mjsonwp module, which is the HTTP server that converts incoming requests into json objects that get sent to the driver programmatically.
"The appium Base driver already has all the REST api routes, validation, and error codes supplied by mjsonwp.
"Appium drivers are designed to have a single testing session per instantiation. This means that one Driver object should be attached to a single device and handle commands from a single client. - Github / Appium / Appium-Base-Driver / lib / basedriver


[Appium] Creating new AndroidDriver (v1.17.1) session
[Appium] Capabilities:
[Appium] app: '/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk'
[Appium] platformName: 'Android'
[Appium] deviceName: 'emulator-5554'

  • Rather boring, isn't it? Watching the same values we already know pass from one service to another to another? But Appium is about to spin up a new AndroidDriver... it read that the platformName is "Android".

[AndroidDriver] AndroidDriver version: 1.17.1
[BaseDriver] Session created with session id: 4bc8afe6-7aa5-4ac8-a42b-55890e777f6d
[AndroidDriver] Getting Java version
[AndroidDriver] Java version is: 1.8.0_121

  • Here we see that the Android Driver has finally been created! And the Appium Base Driver created a new session for it! 

[ADB] Checking whether adb is present
[ADB] Using adb from /Users/ventmahe/Library/Android/sdk/platform-tools/adb

  • What's ADB? It's the "Android Debug Bridge!", part of the command line tools in the Android Software Development Kit. I installed it as a package deal with Android Studio. Yes, technically you can download platform tools as a standalone toolset, but the Android Developers peoplr throw warning after warning that it is not and will not be supported...
"When you start an adb client, the client first checks whether there is an adb server process already running. If there isn't, it starts the server process. When the server starts, it binds to local TCP port 5037 and listens for commands sent from adb clients—all adb clients use port 5037 to communicate with the adb server.

"The server then sets up connections to all running devices. It locates emulators by scanning odd-numbered ports in the range 5555 to 5585, the range used by the first 16 emulators. Where the server finds an adb daemon (adbd), it sets up a connection to that port [...]

"Once the server has set up connections to all devices, you can use adb commands to access those devices. Because the server manages connections to devices and handles commands from multiple adb clients, you can control any device from any client (or from a script).

"[...] To use adb with a device connected over USB, you must enable USB debugging in the device system settings, under Developer options. [...] On Android 4.2 and higher, the Developer options screen is hidden by default. To make it visible, go to Settings > About phone and tap Build number seven times. Return to the previous screen to find Developer options at the bottom". - Android Studio, ADB


[AndroidDriver] Retrieving device list
[ADB] Trying to find a connected android device
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[AndroidDriver] Using device: emulator-5554

  • Oh! Good! It found my Android device, an Android emulator! 
  • It is as if it entered from the command line,  adb devices

[ADB] Checking whether adb is present
[ADB] Using adb from /Users/ventmahe/Library/Android/sdk/platform-tools/adb
[ADB] Setting device id to emulator-5554

  • Now, it is setting the device id it found, using adb. 
  • Hrm. Can it be assumed that if adb was there a split second ago, that adb is still present? 

[BaseDriver] Using local app '/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk'
[AndroidDriver] Checking whether app is actually present
[AndroidDriver] Starting Android session

  • The Appium Base Driver takes from the Desired Capabilities the path and name of the Android app, passes it to the Android Driver, which checks if the app is truly there.
  • It's there? Awesome! Android Driver starts a new Android session!

[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","wait-for-device"]

  • What are those args? Those arguments? 
  • -P: port. -s: serial_number.
  • Wait-for-device waits only as long as the arg daemon has properly started, then exists. 
  • ADB clients all listen to TCP Port 5037 to communicate with a server request.

[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","echo","ping"]

  • Is there a device still connected? Yes?
  • If so, let's start adb running, listening in at Port 5037 for any incoming Appium server messages, once again. 
  • "Shell" starts a remote interactive shell in the target device. From here, you can start various shell commands: https://developer.android.com/studio/command-line/adb.html#shellcommands


[Logcat] Starting logcat capture
"Logcat is a command-line tool that dumps a log of system messages, including stack traces when the device throws an error and messages that you have written from your app with the Log class [...]
"You can run logcat as an adb command or directly in a shell prompt of your emulator or connected device. To view log output using adb, navigate to your SDK platform-tools/ directory and execute":
adb logcat
-- Developer.Android.Studio / Command Line / LogCat


[AndroidDriver] Pushing settings apk to device...

  • Do we have any special settings to go with the apk? 


[ADB] Getting install status for io.appium.settings

  • IO.Appium.Settings is "a small and simple Android application that deals with the system settings. Then the application shuts down. [...] Toggle settings in Android device or emulator".
  • Official docs are https://github.com/appium/io.appium.settings

[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","list","packages","io.appium.settings"]
[ADB] App is installed

  • Once again, we are getting connected devices. 
  • We are going to run the Android Debug Bridge from where Android Studio installed it on my local machine. 
  • What are the arguments? The port is 5037, where Appium has been set up to listen in. 
  • The serial number is set to emulator 5554, our emulator we have running. 
  • This time, though, as we go into the shell in the emulated device, we are going to make a call to the ADB Package Manager (pm) to list all packages. We want to see if io.appium.settings are there. 
  • Need help? Read Android Central and Ten Basic Android Commands You Should Know

"Within an adb shell, you can issue commands with the package manager (pm) tool to perform actions and queries on application packages installed on the device. While in a shell, the syntax is:[...]  pm command
"You can also issue a package manager command directly from adb without entering a remote shell. For example:[...] adb shell pm uninstall com.example.MyApp

list packages [options] filter: Prints all packages, optionally only those whose package name contains the text in filter.

Options:
-f: See their associated file.
-d: Filter to only show disabled packages.
-e: Filter to only show enabled packages.
-s: Filter to only show system packages.
-3: Filter to only show third party packages.
-i: See the installer for the packages.
-u: Also include uninstalled packages.
--user user_id: The user space to query.

[ADB] Getting package info for io.appium.settings
[ADB] Getting connected devices...
[ADB] Checking whether aapt is present
[ADB] Using aapt from /Users/ventmahe/Library/Android/sdk/build-tools/23.0.1/aapt
[ADB] 1 device(s) connected

  • AAPT is the Android Asset Packaging Tool. 
$ aapt
Android Asset Packaging Tool

Usage:
 aapt l[ist] [-v] [-a] file.{zip,jar,apk}
   List contents of Zip-compatible archive.

 aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
   badging          Print the label and icon for the app declared in APK.
   permissions      Print the permissions from the APK.
   resources        Print the resource table from the APK.
   configurations   Print the configurations in the APK.
   xmltree          Print the compiled xmls in the given assets.
   xmlstrings       Print the strings of the given compiled xml assets.
  • "This tool is part of the SDK (and build system) and allows you to view, create, and update Zip-compatible archives (zip, jar, apk). It can also compile resources into binary assets". - ELinux.org
  • After getting the package info, checking it is there in the above step, we are going to use this tool to spy inside the package. 

[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","dumpsys","package","io.appium.settings"]
[ADB] Cannot read version codes of /Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/io.appium.settings/app/build/outputs/apk/settings_apk-debug.apk and/or io.appium.settings. Assuming correct app version is already installed

  • Hrm... settings_apk-debug.apk and/or io.appium.settings could not be found. I don't think I set up anything special. Maybe they can't be found because they are not there? 
  • Once again, we are using the Android Debug Bridge to go to the shell, and use the Android shell commands to investigate what is going on inside the emulator that is running. 
"Dumpsys System Diagnostics. [...] The dumpsys tool runs on the device and provides information about the status of system services. [...] If you run adb shell dumpsys, you’ll get diagnostic output for all system services, which is usually more than you want. For more manageable output, specify the service you would like to examine. For example, the following command:
"$ adb shell dumpsys input
"provides system data for input components such as touchscreens or built-in keyboards". - Source.Android.Com / DumpSys


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","ro.build.version.sdk"]
[ADB] Device API level: 25

  • First step... make sure a connected device is running. 
  • Next step? Let's shell into the running emulator, entering it by port 5037, the Appium server, choosing emulator-5554.
  • This time, we are using the adb shell command "getprop" to investigate "ro.build.version.sdk". 

... Each Android device and emulator has a list of "build properties".

"Android has a single text file named 'build.prop' that determines lots of various system-wide settings on your device. You need root access to edit this file, since it’s stored on the system partition—but the various lines of codes it contains are actually easy to interpret and modify".

... Here, we are grabbing the root property "build version sdk", meaning, what version of operating system?

... It's API 25.

[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","dumpsys","package","io.appium.settings"]
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","dump","io.appium.settings"]

  • Still have an emulator? If so, let's do another adb shell script "dumpsys", looking for the particular package "io.appium.settings". 
  • Still have a emulator? If so let's use the adb shell script command package manger to do a "dumpsys" to take a look at the input output settings for Appium and throw it onto the screen. 
io.appium.settings is a "A small and simple Android application that deals with the system settings. Then the application shuts down." according to https://github.com/appium/io.appium.settings


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","grant","io.appium.settings","android.permission.WRITE_SETTINGS",";","pm","grant","io.appium.settings","android.permission.ACCESS_MOCK_LOCATION",";"]

  • Is the Android device connected? Here is where it gets good! 
  • This time, we are going to go to the device and use the shell script package manager to do something quite different... we are going to get READ AND WRITE PERMISSIONS! Are you excited? I'm excited! The Appium Server is now going to grant us permission to read and write files on the device. 
See all the WRITE_SETTINGS: Appium could have made our phone vibrate, answer a call, leave a voicemail, whatever. 

Instead we are going to grant to io.appium.settings to ACCESS_MOCK_LOCATION:
  • "Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers". - Android Permissions
... I know it has been a while... but I want to mention that the only way the Android Debug Bridge ("adb") has this power over our emulator or physical Android device because we gave it to adb.

"To use adb with a device connected over USB, you must enable USB debugging in the device system settings, under Developer options.
"On Android 4.2 and higher, the Developer options screen is hidden by default. To make it visible, go to Settings > About phone and tap Build numberseven times. Return to the previous  screen to find Developer options at the bottom.
"On some devices, the Developer options screen might be located or named differently.
"You can now connect your device with USB. You can verify that your device is connected by executing adb devices from theandroid_sdk/platform-tools/ directory. If connected, you'll see the device name listed as a 'device.'" - Developer.Android.Com / ADB



[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","grant","io.appium.settings","android.permission.WRITE_SETTINGS",";","pm","grant","io.appium.settings","android.permission.ACCESS_MOCK_LOCATION",";"]

  • And we are going to do the exact same thing we did before... huh? 


[AndroidDriver] Pushing unlock helper app to device...

  • Appium has a helper app to unlock and "wake up" a device. See https://github.com/appium/unlock_apk 
  • Since Appium now has been given read and write permissions, it can install the unlock helper app to your device, no problem. 


[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","install","/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-unlock/bin/unlock_apk-debug.apk"]

  • There it goes! After being pushed onto your device, the helper app, unlock_apk-debug.apk, is now being installed.


[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","install","/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-unlock/bin/unlock_apk-debug.apk"]

  • Um, and there it goes again, attempting to install appium-unlock? But it was just done!

[ADB] Application '/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-unlock/bin/unlock_apk-debug.apk' already installed. Continuing.

  • Yes, we know it was already installed. Next! 

[ADB] Device API level: 25
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","appops","set","io.appium.settings","android:mock_location","allow"]

  • Before, we had to get permissions to use MOCK_LOCATION? Now, we are setting it, with an Android adb shell script program called "appops". 
  • We had "pm", the package manager allows you to install and uninstall software "packages" (such as out Android apps).
  • Now, we have "appops" the App Operations manager that allows us to set the Android property "io.appium,.settings" mock location to "allow".  
"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers". - Android Permissions



[ADB] Getting device platform version
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","ro.build.version.release"]

  • What is the device platform version? First, let's check if we can get the connected device. It's all good?
  • Let's use the adb command, part of the Android Command Line tools, installed on our local computer as a packaged deal when I installed "Android Studio", the only way the Android Developers wanted it. 
  • We are going to communicate through port 5037 with our emulator, attached at "emulator-5554" and shell into the emulator.
  • The shell command Appium is using this time? Getprop. We are getting the Android emulator's root property build version release.


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","wm","size"]

  • Same thing as above! We are using the shell program "wm" to get the size. "wm" is the windows manager. (Want to read more? See the section on "Display" in Developer.Android.Com


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","ro.product.model"]
[ADB] Current device property 'ro.product.model': Android SDK built for x86

  • And now, Appium is checking through ADB the root product model. 
  • It finds the Android Software Development Kit was built for the x86 architecture, that is Intel's x86 (as apposed to the AMD chipset)


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","ro.product.manufacturer"]
[ADB] Current device property 'ro.product.manufacturer': unknown

  • Who manufactured the device that is running? It is listed as unknown because it is an emulator. 

[AndroidDriver] Parsing package and activity from app manifest

  • What is a package? "A package is a namespace that organizes a set of related classes and interfaces. Conceptually you can think of packages as being similar to different folders on your computer. You might keep HTML pages in one folder, images in another, and scripts or applications in yet another. Because software written in the Java programming language can be composed of hundreds or thousands of individual classes, it makes sense to keep things organized by placing related classes and interfaces into packages". - Java Tutorials, What is a Package?
  • What is an activity? "An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View). While activities are often presented to the user as full-screen windows, they can also be used in other ways: as floating windows (via a theme with windowIsFloating set) or embedded inside of another activity (using ActivityGroup)." Developer.Android.Com / Activity 
  • What is the app manifest?

According to Developer.Android.Com / Manifest-Intro:

"Every application must have an AndroidManifest.xml file (with precisely that name) in its root directory. The manifest file provides essential information about your app to the Android system, which the system must have before it can run any of the app's code.
  • "Among other things, the manifest file does the following:
  • "It names the Java package for the application. The package name serves as a unique identifier for the application.
  • "It describes the components of the application, which include the activities, services, broadcast receivers, and content providers that compose the application. It also names the classes that implement each of the components and publishes their capabilities, such as the Intent messages that they can handle. These declarations inform the Android system of the components and the conditions in which they can be launched.
  • "It determines the processes that host the application components.
  • "It declares the permissions that the application must have in order to access protected parts of the API and interact with other applications. It also declares the permissions that others are required to have in order to interact with the application's components.
  • "It lists the Instrumentation classes that provide profiling and other information as the application runs. These declarations are present in the manifest only while the application is being developed and are removed before the application is published.
  • "It declares the minimum level of the Android API that the application requires.
  • "It lists the libraries that the application must be linked against".

[ADB] Checking whether aapt is present

  • Is the Android Asset Packaging Tool there? This aapt tool will help you view, create, and update your APKs.

[ADB] Using aapt from /Users/ventmahe/Library/Android/sdk/build-tools/23.0.1/aapt
[ADB] Extracting package and launch activity from manifest

  • Now we are going to examine the manifest for the package and launch activity.

[ADB] badging package: io.appium.android.apis
[ADB] badging act: io.appium.android.apis.ApiDemos

  • In order to launch a package, we are going to need to know two things: The name of app package, and the app activity, just as when we were attempting to launch and app via Appium Desktop.

[AndroidDriver] Parsed package and activity are: io.appium.android.apis/io.appium.android.apis.ApiDemos

Found it!

  • App package: io.appium.android.apis
  • App Activity: io.appium.android.apis.ApiDemos

[AndroidDriver] Remote apk path is /data/local/tmp/29649242b53e9a67ba855b067422713c.apk

  • Appium is going to take where APIDemos-debug.apk is located in our local computer, and upload it to our Android device (our emulator in this case) somewhere in a temporary directory. 
  • ADB has an "install" command which installs an apk onto a device. 

[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","ls","/data/local/tmp/29649242b53e9a67ba855b067422713c.apk"]

  • Adb now going to check that it is there, accessing the emulator through port 5037, on device emulator-5554, using the Unix shell command "ls", listing the directory, and checking that the apk is there.  

[AndroidDriver] Checking if app is installed
[ADB] Getting install status for io.appium.android.apis
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","list","packages","io.appium.android.apis"]
[ADB] App is installed

  • As a belt-and-suspenders approach, Appium is checking if the app is truly installed by shelling into the emulator-5554 using the package manager to list all packages to make sure that io.appium.android.apis is listed on the device. And it is! 
[AndroidDriver] Apk is already on remote and installed, resetting
[AndroidDriver] Running fast reset (stop and clear)
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","am","force-stop","io.appium.android.apis"]


  • Something must be wrong with the Appium code. It looks like the app is installed and running twice? 
  • For the second instance we are doing a "force-stop", stopping the app from running. 


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","pm","clear","io.appium.android.apis"]

  • Now, we are going to clear the app's cache using the Package Manager. The app data has been stored in the cache for easy retrieval, and must be erased.

[AndroidDriver] Extracting strings from apk /Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk undefined /var/folders/0h/hf79m7zj1xz1hdk0m3t091v8221rx6/T/io.appium.android.apis

  • Now, we are extracting strings in the manifest xml. Not sure what this means


[ADB] Extracting strings for language: default
[ADB] Device API level: 25
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","persist.sys.locale"]
[ADB] Current device property 'persist.sys.locale':

  • As we start extracting the contents of the manifest.xml file, we found that the language has been set to be "default" and the operating system is API level 25.
What is locale? How can you set it through the command line?

From ProfWeb / Setting the Locale:
"The locale (language and country) may be set using the Settings button in the Launcher, choose Language & Input it will immediately change the interface language [...]
"Note: You can only do this if you are either using an AVD or you have rooted your device [...]
Modification can only be done if you have root access so on an AVD or a rooted device. To see the current information:
  • "getprop persist.sys.language
  • "getprop persist.sys.country"


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","getprop","ro.product.locale"]
[ADB] Current device property 'ro.product.locale': en-US

  • Now, we are using adb for grabbing from root the value of the root property, product locale. It is listed as "en-US".
  • "en-US" is the language code for "English - United States" given by the Internet Engineering Task Force (IETF) language tag.
Note that we can have:
  • en-GB: British English
  • en-US: American English
  • en-CA: Canadian English
  • en-IN: Indian English
... Each has its own pronunciations, spellings.

Want to drown in information? Read BP47: Tags for Identifying Languages, on IETF.org.


[ADB] No strings.xml for language 'en', getting default strings.xml

  • Why would there be no strings.xml? What does this mean? 

[ADB] Reading strings from converted strings.json

  • Eh?


[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","push","/var/folders/0h/hf79m7zj1xz1hdk0m3t091v8221rx6/T/io.appium.android.apis/strings.json","/data/local/tmp"]

  • The app activity is at /var/folders/0h/hf79m7zj1xz1hdk0m3t091v8221rx6/T/io.appium.android.apis
  • We are going to push this into a temporary file /data/local/tmp. 

"Use the pull and push commands to copy files to and from an device. Unlike the install command, which only copies an APK file to a specific location, the pull and push commands let you copy arbitrary directories and files to any location in a device". - Developer.Android.Com / ADB
  • Why does Appium do it this way, with a "push" of the directories, instead of an "adb install TheApk.apk"?

[AndroidBootstrap] Watching for bootstrap disconnect

Next, we are going to talk about AppiumBootstrap.

  • Android Bootstrap uses Appium-ADB < https://github.com/appium/appium-adb > which defaults to port 4724. It allows us to perform all adb operations on android device and then some.


[ADB] Forwarding system: 4724 to device: 4724
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","forward","tcp:4724","tcp:4724"]

  • Here, we are setting up port forwarding, for appium to listen to what is happening on the emulator.
  • Readying Android Bootstrap! 
  • Appium-Android-Bootstrap according to Appium's GitHub documentation, is a "JavaScript interface, and Java code, for interacting with Android UI Automator. The system allows ad hoc commands to be sent to the device, which are executed using Android's UIAutomator testing framework".
[UiAutomator] Starting UiAutomator

From Developer.Android.Com / Testing-Libraries / UI Automator:

"The UI Automator testing framework provides a set of APIs to build UI tests that perform interactions on user apps and system apps. The UI Automator APIs allows you to perform operations such as opening the Settings menu or the app launcher in a test device. The UI Automator testing framework is well-suited for writing black box-style automated tests, where the test code does not rely on internal implementation details of the target app.
"The key features of the UI Automator testing framework include:
  • An API to retrieve state information and perform operations on the target device. For more information, see Access to device state.
  • APIs that support cross-app UI testing. For more information, see UI Automator APIs .
  • Requires Android 4.3 (API level 18) or higher.

[UiAutomator] Moving to state 'starting'
[UiAutomator] Parsing uiautomator jar
[UiAutomator] Found jar name: 'AppiumBootstrap.jar'

  • UIAutomator signals that it is starting on your local machine. 
  • It is searching through the UIAutomator java archive file (like a zip file, but for Java).
  • It is looking for AppiumBootstrap's jar file. 

[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","push","/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-android-bootstrap/bootstrap/bin/AppiumBootstrap.jar","/data/local/tmp/"]

  • We are now pushing the directory structure and files for Appium Bootstrap onto the emulator, using ADB into the /data/local/tmp temporary file on the emulator. The UIAutomator will now run, one instance on the emulator or actual device, and one on the computer where Appium Server is running.


[ADB] Attempting to kill all uiautomator processes

[ADB] Getting all processes with uiautomator
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","ps"]
[ADB] No uiautomator process found to kill, continuing...
  • ADB is making sure no other uiautomator processes are running on the emulator or actual device it just pushed the UIAutomator to. If there are leftovers from previous attempts run, we don't want them interfering. 
From Developer.Android.Com / Testing-Libraries / UI Automator: "The UI Automator testing framework provides a UiDevice class to access and perform operations on the device on which the target app is running. You can call its methods to access device properties such as current orientation or display size. The UiDevice class also let you perform actions such as:
  • "Change the device rotation
  • "Press a D-pad button
  • "Press the Back, Home, or Menu buttons
  • "Open the notification shade
  • "Take a screenshot of the current window"

[UiAutomator] Starting UIAutomator
[ADB] Creating ADB subprocess with args: ["-P",5037,"-s","emulator-5554","shell","uiautomator","runtest","AppiumBootstrap.jar","-c","io.appium.android.bootstrap.Bootstrap","-e","pkg","io.appium.android.apis","-e","disableAndroidWatchers",false,"-e","acceptSslCerts",false]


  • Did it work? Did pushing UIAutomator and Appium Boostrap work? Can we now, finally, have the Appium Server controlling what is on the actual Android device or (in this case) emulator?
  • We are going to connect to the emulator once again, using adb shell, but this time we are connecting with "uiautomator", running the uiautomator command, "runtest".


From Stuff.MIT.edu / UIAUTOMATOR: "To run your testcases on the target device, you can use the adb shell command to invoke the uiautomator tool. The syntax is:
adb shell uiautomator runtest <jar> -c <test_class_or_method> [options]
"Here’s an example:
adb shell uiautomator runtest LaunchSettings.jar -c com.uia.example.my.LaunchSettings





"Command-line Options:
"The following table describes the subcommands and options for uiautomator.


"Table 1. Command-line options for uiautomator
"runtest <jar>

"Required. The <jar> argument is the name of one or more JAR files that you deployed to the target device which contain your uiautomator testcases. You can list more than one JAR file by using a space as a separator.

"-c <test_class_or_method>: Required. The <test_class_or_method>argument is a list of one or more specific test classes or test methods from the JARs that you want uiautomator to run.

"Each class or method must be fully qualified with the package name, in one of these formats:
  • package_name.class_name 
  • package_name.class_name#method_name 

"You can list multiple classes or methods by using a space as a separator.

"--nohup: Runs the test to completion on the device even if its parent process is terminated (for example, if the device is disconnected).


"-e <NAME> <VALUE>: Specify other name-value pairs to be passed to test classes. May be repeated. Note: The -e options cannot be combined; you must prefix each option with a separate -e flag".

... UIAutomator is passing along via AndroidBootstrap that disableAndroidWatchers",false,"-e","acceptSslCerts",false.


[UiAutomator] Moving to state 'online'
[AndroidBootstrap] Android bootstrap socket is now connected

  • AndroidBootstrap lives! 
  • The appium-android-bootstrap module provides "an AndroidBootstrap class, which is instantiated with an instance of appium-adb, a system port (defaults to 4724) and an optional web socket". - GitHub of appium-android-bootstrap.
  • The "socket" is of the Java class "ServerSocket". See Java Documentation )
  • "A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to". - Java Tutorials / What is a Socket?

[ADB] Getting connected devices...
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] json loading complete.
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Registered crash watchers.
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Client connected

  • Just in case of problems, Bootstrap in debug mode, explaining things in detail. 
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","dumpsys","window"]
[AndroidDriver] Screen already unlocked, doing nothing

  • If the screen were locked, we could have the screen unlocked it here. 


[ADB] Device API level: 25
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","am","start","-W","-n","io.appium.android.apis/io.appium.android.apis.ApiDemos","-S"]

  • What Android operating system is it? API 25? Check! Device connected? Check! Bring on the next adb shell command, "am", the "activity manager"!

"Within an adb shell, you can issue commands with the activity manager (am) tool to perform various system actions, such as start an activity, force-stop a process, broadcast an intent, modify the device screen properties, and more. While in a shell, the syntax is: [...] am command 

"You can also issue an activity manager command directly from adb without entering a remote shell. For example:
adb shell am start -a android.intent.action.VIEW

"Table 2. Available activity manager commands"
"start [options] intent

"Start an Activity specified by intent. See the Specification for intent arguments.

"Options are:
"-D: Enable debugging.
"-W: Wait for launch to complete.
"--start-profiler file: Start profiler and send results to file.
"-P file: Like --start-profiler, but profiling stops when the app goes idle.
"-R count: Repeat the activity launch count times. Prior to each repeat, the top activity will be finished.
"-S: Force stop the target app before starting the activity.
"--opengl-trace: Enable tracing of OpenGL functions.
"--user user_id | current: Specify which user to run as; if not specified, then run as the current user".
- Developer.Android.Cpm / ADB / AM
  • So, we are using adb to launch the activity manager, start an activity, and wait for the launch to complete for APIDemos, our app's activity! Just in case it already happens to running, we are going to (-S) force stop it first, so we start of fresh.  

[ADB] Waiting for pkg: 'io.appium.android.apis' and activity: 'io.appium.android.apis.ApiDemos' to be focused

  • Yes, yes, yes! Yes! ... ApiDemos, the app we installed onto the emulator is running and launched! 
  • We are just waiting for the main window to gain the focus of the Android emulator. 

... At this point? The app launched and opened up on the emulator I had running! ... 



[ADB] Possible activities, to be checked: io.appium.android.apis.ApiDemos, io.appium.android.apis.io.appium.android.apis.ApiDemos
[ADB] Getting focused package and activity
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","dumpsys","window","windows"]

  • Let's see... does our Android app running on the emulator, ApiDemos, have the focus? 
  • Grab from the Android device whatever is the main focus, the app that is running in the foreground. 
  • We are going to do a system dump and throw what is there in a window... is it what we hoped?


[ADB] Found package: 'io.appium.android.apis' and fully qualified activity name : 'io.appium.android.apis.ApiDemos'

  • We now have proof that the ApiDemos program is running! 


[Appium] New AndroidDriver session created successfully, session 4bc8afe6-7aa5-4ac8-a42b-55890e777f6d added to master session list

  • We just successfully installed UIAutomator, set up a connection between the Appium Server running on your computer and one on the Android device or emulator. We pushed our app's directories onto the emulator. We launched the app's activity. And we proved that the app now was up and running and had the focus!
  • Do you remember when "[BaseDriver] Session created with session id: 4bc8afe6-7aa5-4ac8-a42b-55890e777f6d"? Well, it's now added to the master list! It's about time! 

[BaseDriver] Event 'newSessionStarted' logged at 1495296265108 (12:04:25 GMT-0400 (EDT))

  • Yay! A new session with Appium's base driver, all logged in! ... 
Remember: 
"An appium driver is a module which processes Mobile Json Wire Protocol commands and controls a device accordingly. The commands can either come in over HTTP as json api requests, or they can be passed to the driver object programmatically as already-parsed json object (without the HTTP headers and junk). [...] The appium Base driver already includes the mjsonwp module, which is the HTTP server that converts incoming requests into json objects that get sent to the driver programmatically.
"The appium Base driver already has all the REST api routes, validation, and error codes supplied by mjsonwp. [...] Appium drivers are designed to have a single testing session per instantiation. This means that one Driver object should be attached to a single device and handle commands from a single client. - Github / Appium / Appium-Base-Driver / lib / basedriver



[MJSONWP] Responding to client with driver.createSession() result: {"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk","platformName":"Android","deviceName":"emulator-5554"},"app":"/Users/ventmahe/code/basic_appium_framework/ApiDemos-debug.apk","platformName":"Android","deviceName":"emulator-5554","deviceUDID":"emulator-5554","platformVersion":"7.1.1","deviceScreenSize":"1440x2560","deviceModel":"Android SDK built for x86","deviceManufacturer":"unknown","appPackage":"io.appium.android.apis","appWaitPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","appWaitActivity":"io.appium.android.apis.ApiDemos"}

  • Okay! We have the Mobile JSON Wire Protocol reporting back with the results of the Appium Driver createSession() command.
  • The default driver session is of the Linux platform, does not have web storage, takes screenshots, has JavaScript enabled along with network connectivity.
  • It also has the DesiredCapabilities we passed in. 
  • It also records the stats of the emulator or Android device we are working on. 


[HTTP] <-- POST /wd/hub/session 200 8885 ms - 868

... All of this? ... It took only under nine seconds to do everything from kickoff to now! ....

[HTTP] --> POST /wd/hub/session/4bc8afe6-7aa5-4ac8-a42b-55890e777f6d/timeouts/implicit_wait {"ms":30000}
  • Do you remember when "[BaseDriver] Session created with session id: 4bc8afe6-7aa5-4ac8-a42b-55890e777f6d"? The session id is now being used as a session index for the implicit wait timeouts. 
... Remember... all we are doing here is having Appium install and launch the app. After thirty seconds without a command, we are going to time out.
[MJSONWP] Calling AppiumDriver.implicitWait() with args: [30000,"4bc8afe6-7aa5-4ac8-a42b-55890e777f6d"]
[BaseDriver] Set implicit wait to 30000ms

... Let's put 30 seconds on the clock...
... And the clock starts... now!
... So, how are you doing? Have you enjoyed this? ... I mean not, enjoyed as in you enjoy blowing bubbles on a summer day. But have you enjoyed learning along with me? ...
... This was really fun for me the first ten hours I started researching this...
... I lost count how long this blog entry took after twenty hours of research...
... Why am I doing this, spending countless hours crafting a blog entry not many people will read?...
... Well, I am trying to learn as much as I can as fast as I can. I want to be the best Appium developer I can be... I just started learning about it in March of 2017. Four months so far and look at the many Appium projects I have done! ... If I get caught in yet another layoff, I want to make it as painless for me as possible to get another job! ...
... Okay, I think that has been thirty seconds... Let's see how the app is doing...


[MJSONWP] Responding to client with driver.implicitWait() result: null
[HTTP] <-- POST /wd/hub/session/4bc8afe6-7aa5-4ac8-a42b-55890e777f6d/timeouts/implicit_wait 200 8 ms - 76

  • After 30 seconds, the time ran out on the implicit wait. 
  • We are sending that data back to the Appium server running on our local machine.

[HTTP] --> DELETE /wd/hub/session/4bc8afe6-7aa5-4ac8-a42b-55890e777f6d {}

  • The call comes over the wire... Delete the session id! 

[MJSONWP] Calling AppiumDriver.deleteSession() with args: ["4bc8afe6-7aa5-4ac8-a42b-55890e777f6d"]
[BaseDriver] Event 'quitSessionRequested' logged at 1495296265360 (12:04:25 GMT-0400 (EDT))
[AndroidDriver] Shutting down Android driver

  • Our Appium Driver got the message from the Appium Server! Delete the session! Call the deleteSession() method!
  • The Appium base driver logs the quitSessionRequested, and the Android Driver announces it is shutting down. 


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","am","force-stop","io.appium.android.apis"]

  • Are we connected still? Yes? Good! Let's use the adb shell command Activity Manager "am" to do a force-stop on our application. 

[ADB] Pressing the HOME button

  • Our app is scheduled to recede into the background... 

[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","input","keyevent",3]

  • Are we connected still? Yes? Good! Let's use the adb shell command called "input", where we are going to simulate a keyevent, 3, which is simulating pressing the HOME key. 
Some event_codes according to this event_code discussion on Stack Overflow:


1 -->  "KEYCODE_MENU" 
2 -->  "KEYCODE_SOFT_RIGHT" 
3 -->  "KEYCODE_HOME" 
4 -->  "KEYCODE_BACK" 
5 -->  "KEYCODE_CALL" 
6 -->  "KEYCODE_ENDCALL" 
7 -->  "KEYCODE_0" 
8 -->  "KEYCODE_1" 
9 -->  "KEYCODE_2" 
10 -->  "KEYCODE_3" 
11 -->  "KEYCODE_4" 
12 -->  "KEYCODE_5" 
13 -->  "KEYCODE_6" 
14 -->  "KEYCODE_7" 
15 -->  "KEYCODE_8" 
16 -->  "KEYCODE_9" 
17 -->  "KEYCODE_STAR" 
18 -->  "KEYCODE_POUND" 
19 -->  "KEYCODE_DPAD_UP" 
20 -->  "KEYCODE_DPAD_DOWN" 
21 -->  "KEYCODE_DPAD_LEFT" 
22 -->  "KEYCODE_DPAD_RIGHT" 
23 -->  "KEYCODE_DPAD_CENTER" 
24 -->  "KEYCODE_VOLUME_UP" 
25 -->  "KEYCODE_VOLUME_DOWN" 
26 -->  "KEYCODE_POWER" 
27 -->  "KEYCODE_CAMERA" 
28 -->  "KEYCODE_CLEAR" 

  • Now, our app receded into the background. 


[AndroidBootstrap] Sending command to android: {"cmd":"shutdown"}
[AndroidBootstrap] Received command result from bootstrap
[UiAutomator] Shutting down UiAutomator
[UiAutomator] Moving to state 'stopping'


  • Android Bootstrap sends the final groups of messages to UI Automator through the wormhole... I mean the socket. The command? Shutdown. 
  • UI Automator moves to the "Stopping" state. 


[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"shutdown"}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type SHUTDOWN
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":0,"value":"OK, shutting down"}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Closed client connection

  • Android Bootstrap, in full on Debug mode closes the connection. 


[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: numtests=1
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: stream=.
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: test=testRunServer
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: current=1
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS_CODE: 0
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: stream=
[AndroidBootstrap] [UIAUTO STDOUT] Test results for WatcherResultPrinter=.
[AndroidBootstrap] [UIAUTO STDOUT] Time: 2.578
[AndroidBootstrap] [UIAUTO STDOUT] OK (1 test)
[AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS_CODE: -1

  • In one last flurry of activity, Android Bootstrap talks about how it ran one test, the UiAutomatorTestRunner. 
  • The watch it set before, it is stopped. 2.578 seconds.
  • There are no more tests to be run. Android Bootstrap is done. 


[UiAutomator] UiAutomator shut down normally
[UiAutomator] Moving to state 'stopped'

  • So long, UiAutomator!

[ADB] Attempting to kill all uiautomator processes
[ADB] Getting all processes with uiautomator
[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","ps"]

  • Is this an error? Or is this a safety measure, such as a "Double Tap" in the movie, Zombieland


[ADB] No uiautomator process found to kill, continuing...
[UiAutomator] Moving to state 'stopped'

  • Goodbye, zombie UIAutomator! ... I am sorry, but I need to report you as a bug to the Android Developers. I am a QA Engineer after all!


[Logcat] Stopping logcat capture

  • And goodbye logcat!


[ADB] Getting connected devices...
[ADB] 1 device(s) connected
[ADB] Running '/Users/ventmahe/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","emulator-5554","shell","am","force-stop","io.appium.unlock"]
  • Once again we are using ADB, the Android Debug Bridge to go to the device on port 5037, to the emulated Android device, and entering a shell script. 
  • am: The Activity Manager. 
  • force-stop: Everything halted.

[AndroidDriver] Not cleaning generated files. Add `clearSystemFiles` capability if wanted.

  • Hrm. Should the generated files be cleaned up? Is this a bug?


[Appium] Removing session 4bc8afe6-7aa5-4ac8-a42b-55890e777f6d from our master session list
  • Remember that session we added to the master session list, adding it by session id? Parting is such sweet sorrow!
[BaseDriver] Event 'quitSessionFinished' logged at 1495296266614 (12:04:26 GMT-0400 (EDT))

  • Now, the Appium Base Driver has left the stage. 
  • All we have left is the Appium Server. 

[MJSONWP] Received response: null
[MJSONWP] But deleting session, so not returning
[MJSONWP] Responding to client with driver.deleteSession() result: null
[HTTP] <-- DELETE /wd/hub/session/4bc8afe6-7aa5-4ac8-a42b-55890e777f6d 200 1260 ms - 76

  • "All Quiet on the Western Front".
  • "The Rest ... is Silence". 


-T.J. Maher
Twitter | LinkedIn | GitHub

// Sr. QA Engineer, Software Engineer in Test, Software Tester since 1996.
// Contributing Writer for TechBeacon.
// "Looking to move away from manual QA? Follow Adventures in Automation on Facebook!"