Skip to main content

Unlocking Your Android Test Devices' Potential. Literally.

"Education is the key to unlock the golden door of freedom."
~George Washington Carver
 The successful creation and management of a device lab at my company has required many hours of work from an autodidactic polymath. Unfortunately that responsibility fell to rest on me instead (with an audible *THUMP*). This is another piece of the narrative of my education.

Waking and Unlocking Jelly Bean Devices Automatically

One of the common traits to all Android devices we use in house is that they're all provisioned with a Google Apps account for remote management purposes. This includes "personal" devices (BYOD is alive and well) and lab devices. Under the auspices of Google's MDM scheme, there is no concept of segregating collections of devices and applying rules regarding PIN strength, screen timeouts, etc (at least according the the domain admin whose words I have no need to distrust). This is frustrating to me since my first experience with MDM was back in 2007 with Microsoft's first attempts at it in System Center Configuration Manager and Windows Mobile 6.5 and 7. At least with SCCM, we could create collections and manage them with unique and overlapping rulesets. Come on, Google. You're getting beaten by SCCM 2007. Okay, I digress.

There is a lot of room for investigation here but suffice it to say newer devices are not able to use the old "keep screen awake while charging" feature on devices in my lab. I am not the Google Apps domain admin and do not have access to the admin console to investigate these settings or work arounds. At least in the case of Jelly Bean, there is a fairly handy work-around based on UIAutomator's access to the lock screen.

Broken down it looks like this:

Problem - Unblock UI automation at the lock screen automatically.
Solution - Use UIAutomator on JellyBean devices to wake the screen, check for lock, enter the pin, and unlock the device.
Bonus - Leave this in place to be repeatable by any arbitrary test on the CI server.

Pseudo code:

FakeTestCase(){
    if(device screen isn't on){
        getUiDevice().wakeUp()
    } catch (exception e) {
        handle exception()
    }
   
    UiWatcher LockScreenPinHandler = new UiWatcher() {
    boolean checkForCondition(){
        UiObject SomethingUnique = get something unique about the lock screen
        if(SomethingUnique.exists()){
            get PinEntryField
            set Pin in PinEntryField
            hit Enter
        }
    
    }

    RegisterWatcher
    RunWatcher

    UiObject HomeScreenAppsButton = get home screen apps button;
    assert(HomeScreenAppsButton.isShown/Visible/Clickable/Whatever())

}

In normal usage:

By creating a java project and building a JAR that contains the UIAutomator test logic above, I can simply upload that jar to /data/local/tmp on the affected devices and run the "test" prior to running any other UI automation, be it Cucumber, JUnit, Monkey Runner, or even UIAutomator-based. In Jenkins it would look like the following (where $DEVICE_SERIAL is an environment variable corresponding to your Android device):

#run DeviceUnlocker.jar in order to wake/unlock device
adb -s $DEVICE_SERIAL shell uiautomator runtest DeviceUnlocker.jar -c com.dummmycompany.DeviceUnlocker.DeviceUnlockingPseudoTest

SAMPLE CODE: 


Comments

  1. Can u please check the option "stay awake" from USB debugging menu list .. so when u r running your automated test device will be always ON .. BTW your solution is nice .. thanks for your post ..

    ReplyDelete
  2. HI Sandip,
    I've tried that but because my devices are under Google Apps management, the domain admin has dictated that they all have a screen timeout and that policy is enforced even on devices in my lab. That's right. This whole thing only exists because of a stupid scenario most people should be able to completely avoid.

    ReplyDelete

Post a Comment

Popular posts from this blog

Jenkins + Devices + AndroidJUnitRunner

New Android build system and test runner, same goose chase using undocumented features and hacks

As I've posted before, I am a big fan of Jenkins. It is extremely flexible, open source, and supported by a staggering array of plugins actively developed by engineers running over 100,000 instances of the server worldwide. With it's distributed node model, you can even build your own device cloud for hosting enterprise-scale automation, economizing hardware investments by sharing resources across multiple projects as well as speeding up automation by parallelizing test runs. I had been using a Jenkins-based system in the past to support instrumentation automation with Robotium quite happily. For the last couple years however, my work hasn't required that as much and I've found myself doing a lot more manual testing and using UiAutomator which didn't require a tight integration between the product codebase and the test code. As a result, I've been slow to adopt the…

UiAutomator and Watchers: Adding Async Robustness to UI Automation

"I'm looking over your shoulder... only because I've got your back." ~ Stephen Colbert
After my recent UiAutomator review a user brought up an important question about the use of UiWatcher. The watchers serve as async guardians of the test flow, making sure the odd dialog window doesn't completely frustrate your tests. Having a tool that automatically watches your back when you're focused on the functional flow of your tests is awesome. 100% pure awesomesauce. Since the API documentation on watchers is scant and the UI Testing tutorial on the Android dev guide doesn't cover their use in depth, I figured I should add a post here that goes over a simple scenario demonstrating how to use this fundamentally important UI automation tool.

In my example code below, I'm using uiautomator to launch the API Demo app (meaning run this against an Emulator built in API level 17 - I used the Galaxy Nexus image included in the latest ADT and platform tools). The te…

Run-As Like the Wind: Getting private app data off non-rooted devices using adb run-as and a debuggable app

"You're some kind of big, fat, smart-bug aren't you?"
~Johnny Rico, Starship Troopers (1997) One of the most important things about writing bugs is making them descriptive but concise. Screenshots, video, debug logging, and hardware snapshots are all fairly standard or available to Android testers these days and can save you enormously on text when communicating what constitutes the bug. Sometimes though, the app gets into a weird state due to some transient data issue where you may not own the API or the complexity with forcing the app data into a certain state is prohibitively high. In those cases it is very handy to directly inspect the data the app has in its own directories.

Getting at this data is trivial on emulators and rooted devices but due to file system permissions, this data is otherwise completely private to the app itself. If you're like me, you tend to test using devices rather than emulators and you probably prefer not to root your devices since t…