diff --git a/wlauto/workloads/skypeecho/__init__.py b/wlauto/workloads/skypeecho/__init__.py index 37b77d0b..b77969f3 100644 --- a/wlauto/workloads/skypeecho/__init__.py +++ b/wlauto/workloads/skypeecho/__init__.py @@ -13,7 +13,7 @@ # limitations under the License. # -import os +import os.path as op import time from wlauto import AndroidUiAutoBenchmark, Parameter @@ -28,7 +28,19 @@ SKYPE_ACTION_URIS = { class SkypeEcho(AndroidUiAutoBenchmark): name = 'skypeecho' - description = 'Workload that makes a Skype test call' + description = ''' + Workload that makes Skype calls + + It allows for the agenda to decide whether to make a voice call or a video call. + Credentials for the user account used to log into the Skype app have to be provided + in the agenda, as well as the display name and skype ID of the contact to call. + + Other optional arguments allow controlling the duration of the call, whether the + call includes video or voice only, and whether to collect sys dumps. + + For reliable testing, this workload requires a good and stable internet connection, + preferably on Wi-Fi. + ''' package = 'com.skype.raider' activity = '' # Skype has no default 'main' activity @@ -37,9 +49,6 @@ class SkypeEcho(AndroidUiAutoBenchmark): instrumentation_log = '{}_instrumentation.log'.format(name) 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 @@ -52,16 +61,27 @@ class SkypeEcho(AndroidUiAutoBenchmark): 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('action', kind=str, allowed_values=['voice', 'video'], default='video', + description='Action to take - either video (default) or voice call'), Parameter('use_gui', kind=bool, default=True, description='Specifies whether to use GUI or direct Skype URI'), + Parameter('dumpsys_enabled', kind=bool, default=True, + description=''' + If ``True``, dumpsys captures will be carried out during the test run. + The output is piped to log files which are then pulled from the phone. + '''), ] def __init__(self, device, **kwargs): super(SkypeEcho, self).__init__(device, **kwargs) - self.output_file = os.path.join(self.device.working_directory, self.instrumentation_log) + self.output_file = op.join(self.device.working_directory, self.instrumentation_log) + self.run_timeout = self.duration + 60 + + def validate(self): + super(SkypeEcho, self).validate() self.uiauto_params['results_file'] = self.output_file + self.uiauto_params['dumpsys_enabled'] = self.dumpsys_enabled + self.uiauto_params['output_dir'] = self.device.working_directory if self.use_gui: self.uiauto_params['my_id'] = self.login_name self.uiauto_params['my_pwd'] = self.login_pass @@ -69,7 +89,6 @@ class SkypeEcho(AndroidUiAutoBenchmark): 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() ======') @@ -96,11 +115,11 @@ class SkypeEcho(AndroidUiAutoBenchmark): def update_result(self, context): self.logger.info('===== update_result() ======') super(SkypeEcho, self).update_result(context) - # if not self.dumpsys_enabled: - # return + if not self.dumpsys_enabled: + return self.device.pull_file(self.output_file, context.output_directory) - results_file = os.path.join(context.output_directory, self.instrumentation_log) + results_file = op.join(context.output_directory, self.instrumentation_log) # process results and add them using # context.result.add_metric @@ -116,9 +135,9 @@ class SkypeEcho(AndroidUiAutoBenchmark): self.logger.info('===== teardown() ======') super(SkypeEcho, self).teardown(context) # Pull log files - for entry in self.device.listdir(self.device.working_directory): + wd = self.device.working_directory + for entry in self.device.listdir(wd): if entry.startswith(self.name) and entry.endswith(".log"): - self.device.pull_file(os.path.join(self.device.working_directory, entry), - context.output_directory) - self.device.delete_file(os.path.join(self.device.working_directory, entry)) + self.device.pull_file(op.join(wd, entry), context.output_directory) + self.device.delete_file(op.join(wd, entry)) # 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 deleted file mode 100644 index 3f507bb6..00000000 Binary files a/wlauto/workloads/skypeecho/bin/classes/com/arm/wlauto/uiauto/BaseUiAutomation.class and /dev/null differ diff --git a/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar b/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar index 61a76b3f..7f8e4933 100644 Binary files a/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar and b/wlauto/workloads/skypeecho/com.arm.wlauto.uiauto.skypeecho.jar differ 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 index 1656c407..4d73ab1a 100644 --- a/wlauto/workloads/skypeecho/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java +++ b/wlauto/workloads/skypeecho/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java @@ -3,7 +3,7 @@ package com.arm.wlauto.uiauto.skypeecho; import java.io.File; import java.io.BufferedWriter; import java.io.FileWriter; -import java.util.HashMap; +import java.util.TreeMap; import java.util.Map; import java.util.Map.Entry; @@ -25,17 +25,47 @@ import com.arm.wlauto.uiauto.UxPerfUiAutomation; public class UiAutomation extends UxPerfUiAutomation { - public static String TAG = "uxperf_skypeecho"; + public static final String TAG = "skypeecho"; + public static final String PACKAGE = "com.skype.raider"; + public static final String PACKAGE_ID = "com.skype.raider:id/"; - 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 sendSmsButtonResourceId = PACKAGE_ID + "chat_menu_item_send_sms"; + public static String voiceCallButtonResourceId = PACKAGE_ID + "chat_menu_item_call_voice"; + public static String videoCallButtonResourceId = PACKAGE_ID + "chat_menu_item_call_video"; + public static String endCallButtonResourceId = PACKAGE_ID + "call_end_button"; public static String noContactMessage = "Could not find contact \"%s\" in the contacts list."; - private Map results = new HashMap(); + private Map results = new TreeMap(); + private boolean dumpsysEnabled; + private String outputDir; + + private static Arguments args; + + private static final class Arguments { + String loginName; + String loginPass; + String contactSkypeid; + String contactName; + int callDuration; + String callType; + String resultsFile; + String outputDir; + boolean dumpsysEnabled; + } + + private static Arguments parseBundle(Bundle bundle) { + Arguments args = new Arguments(); + args.loginName = bundle.getString("my_id"); + args.loginPass = bundle.getString("my_pwd"); + args.contactSkypeid = bundle.getString("skypeid"); + args.contactName = bundle.getString("name").replace("_", " "); + args.callDuration = Integer.parseInt(bundle.getString("duration")); + args.callType = bundle.getString("action"); + args.resultsFile = bundle.getString("results_file"); + args.outputDir = bundle.getString("output_dir"); + args.dumpsysEnabled = bundle.getBoolean("dumpsys_enabled"); + return args; + } public void runUiAutomation() throws Exception { // Get Params @@ -45,22 +75,28 @@ public class UiAutomation extends UxPerfUiAutomation { 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")); + String callType = parameters.getString("action"); String resultsFile = parameters.getString("results_file"); + outputDir = parameters.getString("output_dir", "/sdcard/wa-working"); + dumpsysEnabled = parameters.getBoolean("dumpsys_enabled", true); // Run tests Timer overallTimer = new Timer(); - Timer callTimer = new Timer(); overallTimer.start(); handleLoginScreen(loginName, loginPass); selectContact(contactName, contactSkypeid); - callTimer.start(); - makeCall(callDuration, isVideo); - callTimer.end(); + if ("video".equalsIgnoreCase(callType)) { + videoCallTest(callDuration); + } else if ("voice".equalsIgnoreCase(callType)) { + voiceCallTest(callDuration); + } else { + // both ? + // voiceCallTest(callDuration); + // videoCallTest(callDuration); + } overallTimer.end(); // Save results - results.put("call_test", callTimer); results.put("overall_test", overallTimer); saveResults(results, resultsFile); } @@ -79,13 +115,41 @@ public class UiAutomation extends UxPerfUiAutomation { out.close(); } - public void selectContact(String name, String id) throws Exception { - // UiObject peopleTab = new UiObject(selector.text("People")); - UiObject peopleTab = getUiObjectByDescription("People", "android.widget.TextView"); + private void handleLoginScreen(String username, String password) throws Exception { + String useridResoureId = PACKAGE_ID + "sign_in_userid"; + String nextButtonResourceId = PACKAGE_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 = PACKAGE_ID + "signin_skypename"; + String passwordResoureId = PACKAGE_ID + "signin_password"; + String signinButtonResourceId = PACKAGE_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(); + } + + private void selectContact(String name, String id) throws Exception { + Timer timer = new Timer(); + timer.start(); + UiObject peopleTab; + // Open the 'People' tab aka contacts view + // On phones, it is represented by an image with description + // On tablets, it the full text is shown without a description + try { + peopleTab = getUiObjectByDescription("People", "android.widget.TextView"); + } catch (UiObjectNotFoundException e) { + peopleTab = getUiObjectByText("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 + // 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"); @@ -94,52 +158,50 @@ public class UiAutomation extends UxPerfUiAutomation { // contactCard = getUiObjectByText(id, "android.widget.TextView"); } contactCard.clickAndWaitForNewWindow(); + timer.end(); + results.put("select_contact", timer); } - public void makeCall(int duration, boolean video) throws Exception { + private void voiceCallTest(int duration) throws Exception { + String testTag = "voice_call"; + Timer timer = new Timer(); + timer.start(); + makeCall(duration, false, testTag); + timer.end(); + results.put(testTag, timer); + } + + private void videoCallTest(int duration) throws Exception { + String testTag = "video_call"; + Timer timer = new Timer(); + timer.start(); + makeCall(duration, true, testTag); + timer.end(); + results.put(testTag, timer); + } + + private void makeCall(int duration, boolean video, String testTag) throws Exception { + String viewName = "com.skype.android.app.calling.CallActivity"; + String dumpsysTag = TAG + "_" + testTag; + int viewTimeout = 5000; + if (video && dumpsysEnabled) { + initDumpsysSurfaceFlinger(PACKAGE, viewName); + initDumpsysGfxInfo(PACKAGE); + } + // 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(); + // callButton.clickAndWaitForNewWindow(); sleep(duration); // endCall(); + + if (video && dumpsysEnabled) { + exitDumpsysSurfaceFlinger(PACKAGE, viewName, new File(outputDir, dumpsysTag + "_surface_flinger.log")); + exitDumpsysGfxInfo(PACKAGE, new File(outputDir, dumpsysTag + "_gfxinfo.log")); + } } - /* - // TODO Needs to be run on UI thread after sleep - public void endCall() { - final UiObject endButton = getUiObjectByResourceId(endCallButtonResourceId, "android.widget.ImageView"); - final UiObject endButton = getUiObjectByResourceId(endCallButtonResourceId, "com.skype.android.widget.SymbolView"); - 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(); - } }