diff --git a/wlauto/workloads/.gitignore b/wlauto/workloads/.gitignore new file mode 100644 index 00000000..3048cd49 --- /dev/null +++ b/wlauto/workloads/.gitignore @@ -0,0 +1,3 @@ +*.yaml +*.apk +*.json diff --git a/wlauto/workloads/skypeecho/__init__.py b/wlauto/workloads/skypeecho/__init__.py new file mode 100644 index 00000000..5421b7b7 --- /dev/null +++ b/wlauto/workloads/skypeecho/__init__.py @@ -0,0 +1,100 @@ +# Copyright 2014-2016 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import time + +from wlauto import AndroidUiAutoBenchmark, Parameter + + +SKYPE_ACTION_URIS = { + 'call': 'call', + 'video': 'call&video=true', +} + + +class SkypeEcho(AndroidUiAutoBenchmark): + + name = 'skypeecho' + description = 'Workload that makes a Skype test call' + package = 'com.skype.raider' + activity = '' + # Skype has no default 'main' activity + launch_main = False # overrides extended class + + parameters = [ + # Workload parameters go here e.g. + # Parameter('example_parameter', kind=int, allowed_values=[1,2,3], default=1, override=True, mandatory=False, + # description='This is an example parameter') + Parameter('login_name', kind=str, mandatory=True, + description=''' + Account to use when logging into the device from which the call will be made + '''), + Parameter('login_pass', kind=str, mandatory=True, + description='Password associated with the account to log into the device'), + Parameter('contact_skypeid', kind=str, mandatory=True, + description='This is the Skype ID of the contact to call from the device'), + Parameter('contact_name', kind=str, mandatory=True, + description='This is the contact display name as it appears in the people list'), + Parameter('duration', kind=int, default=60, + description='This is the duration of the call in seconds'), + Parameter('action', kind=str, allowed_values=['voice', 'video'], default='voice', + description='Action to take - either voice (default) or video call'), + Parameter('use_gui', kind=bool, default=True, + description='Specifies whether to use GUI or direct Skype URI'), + ] + + def __init__(self, device, **kwargs): + super(SkypeEcho, self).__init__(device, **kwargs) + if self.use_gui: + self.uiauto_params['my_id'] = self.login_name + self.uiauto_params['my_pwd'] = self.login_pass + self.uiauto_params['skypeid'] = self.contact_skypeid + self.uiauto_params['name'] = self.contact_name.replace(' ', '_') + self.uiauto_params['duration'] = self.duration + self.uiauto_params['action'] = self.action + self.run_timeout = self.duration + 30 + + def setup(self, context): + self.logger.info('===== setup() ======') + if self.use_gui: + super(SkypeEcho, self).setup(context) + self.device.execute('am force-stop {}'.format(self.package)) + self.device.execute('am start -W -a android.intent.action.VIEW -d skype:dummy?dummy') + time.sleep(1) + else: + self.device.execute('am force-stop {}'.format(self.package)) + + def run(self, context): + self.logger.info('===== run() ======') + if self.use_gui: + super(SkypeEcho, self).run(context) + else: + data_uri = 'skype:{}?{}'.format(self.contact_skypeid, SKYPE_ACTION_URIS[self.action]) + command = 'am start -W -a android.intent.action.VIEW -d "{}"'.format(data_uri) + self.logger.debug(self.device.execute(command)) + self.logger.debug('Call started; waiting for {} seconds...'.format(self.duration)) + time.sleep(self.duration) + self.device.execute('am force-stop {}'.format(self.package)) + + def update_result(self, context): + pass + # super(SkypeEcho, self).update_result(context) + # process results and add them using + # context.result.add_metric + + def teardown(self, context): + self.logger.info('===== teardown() ======') + super(SkypeEcho, self).teardown(context) + # self.device.execute('am force-stop {}'.format(self.package)) diff --git a/wlauto/workloads/skypeecho/bin/classes/com/arm/wlauto/uiauto/BaseUiAutomation.class b/wlauto/workloads/skypeecho/bin/classes/com/arm/wlauto/uiauto/BaseUiAutomation.class new file mode 100644 index 00000000..3f507bb6 Binary files /dev/null and b/wlauto/workloads/skypeecho/bin/classes/com/arm/wlauto/uiauto/BaseUiAutomation.class differ diff --git a/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar b/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar new file mode 100644 index 00000000..dcabf03b Binary files /dev/null and b/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar differ diff --git a/wlauto/workloads/skypeecho/template-agenda.mustache b/wlauto/workloads/skypeecho/template-agenda.mustache new file mode 100644 index 00000000..d861d194 --- /dev/null +++ b/wlauto/workloads/skypeecho/template-agenda.mustache @@ -0,0 +1,12 @@ +global: + iterations: 1 +workloads: + - id: {{workload_id}} + name: skypeecho + params: + login_name: {{login_name}} + login_pass: {{login_pass}} + contact_skypeid: {{contact_skypeid}} + contact_name: {{contact_name}} + duration: {{duration}} + action: {{action}} diff --git a/wlauto/workloads/skypeecho/uiauto/build.sh b/wlauto/workloads/skypeecho/uiauto/build.sh new file mode 100755 index 00000000..776bd5b8 --- /dev/null +++ b/wlauto/workloads/skypeecho/uiauto/build.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +class_dir=bin/classes/com/arm/wlauto/uiauto +base_class=`python -c "import os, wlauto; print os.path.join(os.path.dirname(wlauto.__file__), 'common', 'android', '*.class')"` +mkdir -p $class_dir +cp $base_class $class_dir + +ant build + +exit_code=$? +if [[ $exit_code -ne 0 ]]; then + echo "ERROR: ant build exited with code $exit_code" && exit $exit_code +fi + +if [[ -f bin/com.arm.wlauto.uiauto.skypeecho.jar ]]; then + cp bin/com.arm.wlauto.uiauto.skypeecho.jar .. +fi diff --git a/wlauto/workloads/skypeecho/uiauto/build.xml b/wlauto/workloads/skypeecho/uiauto/build.xml new file mode 100644 index 00000000..77c86082 --- /dev/null +++ b/wlauto/workloads/skypeecho/uiauto/build.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wlauto/workloads/skypeecho/uiauto/project.properties b/wlauto/workloads/skypeecho/uiauto/project.properties new file mode 100644 index 00000000..6e18427a --- /dev/null +++ b/wlauto/workloads/skypeecho/uiauto/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-21 diff --git a/wlauto/workloads/skypeecho/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java b/wlauto/workloads/skypeecho/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java new file mode 100644 index 00000000..60253868 --- /dev/null +++ b/wlauto/workloads/skypeecho/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java @@ -0,0 +1,105 @@ +package com.arm.wlauto.uiauto.skypeecho; + +import java.lang.Runnable; + +import android.app.Activity; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.KeyEvent; + +// Import the uiautomator libraries +import com.android.uiautomator.core.UiObject; +import com.android.uiautomator.core.UiObjectNotFoundException; +import com.android.uiautomator.core.UiScrollable; +import com.android.uiautomator.core.UiSelector; +import com.android.uiautomator.testrunner.UiAutomatorTestCase; + +import com.arm.wlauto.uiauto.BaseUiAutomation; + +public class UiAutomation extends BaseUiAutomation { + + public static String TAG = "uxperf_skypeecho"; + + public static String PACKAGE = "com.skype.raider"; + + public static String sendSmsButtonResourceId = "com.skype.raider:id/chat_menu_item_send_sms"; + public static String voiceCallButtonResourceId = "com.skype.raider:id/chat_menu_item_call_voice"; + public static String videoCallButtonResourceId = "com.skype.raider:id/chat_menu_item_call_video"; + public static String endCallButtonResourceId = "com.skype.raider:id/call_end_button"; + public static String noContactMessage = "Could not find contact \"%s\" in the contacts list."; + + public void runUiAutomation() throws Exception { + Bundle parameters = getParams(); + String loginName = parameters.getString("my_id"); + String loginPass = parameters.getString("my_pwd"); + String contactSkypeid = parameters.getString("skypeid"); + String contactName = parameters.getString("name").replace("_", " "); + int callDuration = Integer.parseInt(parameters.getString("duration")); + boolean isVideo = "video".equals(parameters.getString("action")); + + handleLoginScreen(loginName, loginPass); + selectContact(contactName, contactSkypeid); + makeCall(callDuration, isVideo); + } + + public void selectContact(String name, String id) throws Exception { + // UiObject peopleTab = new UiObject(selector.text("People")); + UiObject peopleTab = getUiObjectByDescription("People", "android.widget.TextView"); + peopleTab.click(); + + // On first startup, the app may take a while to load the display name, so try twice + // before declaring failure + UiObject contactCard; + try { + contactCard = getUiObjectByText(name, "android.widget.TextView"); + } catch (UiObjectNotFoundException e) { + contactCard = getUiObjectByText(name, "android.widget.TextView"); + // contactCard = getUiObjectByText(id, "android.widget.TextView"); + } + contactCard.clickAndWaitForNewWindow(); + } + + public void makeCall(int duration, boolean video) throws Exception { + // String resource = video ? videoCallButtonResourceId : voiceCallButtonResourceId; + // UiObject callButton = new UiObject(new UiSelector().resourceId(resource)); + String description = video ? "Video call" : "Call options"; + UiObject callButton = new UiObject(new UiSelector().descriptionContains(description)); + callButton.click(); + sleep(duration); + // TODO Needs to be run on UI thread after sleep + /* + final UiObject endButton = getUiObjectByResourceId(endCallButtonResourceId, "android.widget.ImageView"); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + try { + endButton.click(); + } catch (UiObjectNotFoundException e) { + // Do nothing + } + } + }, 10000); + */ + } + + public void handleLoginScreen(String username, String password) throws Exception { + String useridResoureId = "com.skype.raider:id/sign_in_userid"; + String nextButtonResourceId = "com.skype.raider:id/sign_in_next_btn"; + UiObject useridField = new UiObject(new UiSelector().resourceId(useridResoureId)); + UiObject nextButton = new UiObject(new UiSelector().resourceId(nextButtonResourceId)); + useridField.setText(username); + nextButton.clickAndWaitForNewWindow(); + + String skypenameResoureId = "com.skype.raider:id/signin_skypename"; + String passwordResoureId = "com.skype.raider:id/signin_password"; + String signinButtonResourceId = "com.skype.raider:id/sign_in_btn"; + // UiObject skypenameField = new UiObject(new UiSelector().resourceId(skypenameResoureId)); + UiObject passwordField = new UiObject(new UiSelector().resourceId(passwordResoureId)); + UiObject signinButton = new UiObject(new UiSelector().resourceId(signinButtonResourceId)); + // skypenameField.setText(username); + passwordField.setText(password); + signinButton.clickAndWaitForNewWindow(); + } +}