"Education is the key to unlock the golden door of freedom."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.
~George Washington Carver
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
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 ..
ReplyDeleteHI Sandip,
ReplyDeleteI'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.