mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-10-30 22:54:18 +00:00 
			
		
		
		
	Merge pull request #241 from jimboatarm/skype_uxperf
Add Skype workload
This commit is contained in:
		| @@ -138,6 +138,11 @@ class ApkWorkload(Workload): | |||||||
|     :view: The class of the main view pane of the app. This needs to be defined in order |     :view: The class of the main view pane of the app. This needs to be defined in order | ||||||
|            to collect SurfaceFlinger-derived statistics (such as FPS) for the app, but |            to collect SurfaceFlinger-derived statistics (such as FPS) for the app, but | ||||||
|            may otherwise be left as ``None``. |            may otherwise be left as ``None``. | ||||||
|  |     :launch_main: If ``False``, the default activity will not be launched (during setup), | ||||||
|  |                   allowing workloads to start the app with an intent of their choice in | ||||||
|  |                   the run step. This is useful for apps without a launchable default/main | ||||||
|  |                   activity or those where it cannot be launched without intent data (which | ||||||
|  |                   is provided at the run phase). | ||||||
|     :install_timeout: Timeout for the installation of the APK. This may vary wildly based on |     :install_timeout: Timeout for the installation of the APK. This may vary wildly based on | ||||||
|                       the size and nature of a specific APK, and so should be defined on |                       the size and nature of a specific APK, and so should be defined on | ||||||
|                       per-workload basis. |                       per-workload basis. | ||||||
| @@ -160,6 +165,7 @@ class ApkWorkload(Workload): | |||||||
|     min_apk_version = None |     min_apk_version = None | ||||||
|     max_apk_version = None |     max_apk_version = None | ||||||
|     supported_platforms = ['android'] |     supported_platforms = ['android'] | ||||||
|  |     launch_main = True | ||||||
|  |  | ||||||
|     parameters = [ |     parameters = [ | ||||||
|         Parameter('install_timeout', kind=int, default=300, |         Parameter('install_timeout', kind=int, default=300, | ||||||
| @@ -214,7 +220,8 @@ class ApkWorkload(Workload): | |||||||
|         if self.check_apk: |         if self.check_apk: | ||||||
|             self.check_apk_version() |             self.check_apk_version() | ||||||
|  |  | ||||||
|         self.launch_package() |         if self.launch_main: | ||||||
|  |             self.launch_package() # launch default activity without intent data | ||||||
|         self.device.execute('am kill-all')  # kill all *background* activities |         self.device.execute('am kill-all')  # kill all *background* activities | ||||||
|         self.device.clear_logcat() |         self.device.clear_logcat() | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								wlauto/workloads/skype/__init__.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										99
									
								
								wlauto/workloads/skype/__init__.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,99 @@ | |||||||
|  | #    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 AndroidUxPerfWorkload, Parameter | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Skype(AndroidUxPerfWorkload): | ||||||
|  |  | ||||||
|  |     name = 'skype' | ||||||
|  |     description = ''' | ||||||
|  |     A workload to perform standard productivity tasks within Skype. The | ||||||
|  |     workload logs in to the Skype application, selects a recipient from the | ||||||
|  |     contacts list and then initiates either a voice or video call. | ||||||
|  |  | ||||||
|  |     Test description: | ||||||
|  |  | ||||||
|  |     1. Open Skype application | ||||||
|  |     2. Log in to a pre-defined account | ||||||
|  |     3. Select a recipient from the Contacts list | ||||||
|  |     4. Initiate either a ``voice`` or ``video`` call for ``duration`` time (in seconds) | ||||||
|  |  | ||||||
|  |     **Skype Setup** | ||||||
|  |  | ||||||
|  |        - You should install Skype client from Google Play Store on the device | ||||||
|  |          (this was tested with client version 7.01.0.669; other recent versions | ||||||
|  |          should also work). | ||||||
|  |        - You must have a Skype account set up. | ||||||
|  |        - The contact to be called must be added (and has accepted) to the | ||||||
|  |          account. It's possible to have multiple contacts in the list, however | ||||||
|  |          the contact to be called *must* be visible on initial navigation to the | ||||||
|  |          list. | ||||||
|  |        - For video calls the contact must be able to received the call. This | ||||||
|  |          means that there must be  a Skype client running (somewhere) with the | ||||||
|  |          contact logged in and that client must have been configured to | ||||||
|  |          auto-accept calls from the account on the device (how to set this | ||||||
|  |          varies between different versions of Skype and between platforms -- | ||||||
|  |          please search online for specific instructions). | ||||||
|  |          https://support.skype.com/en/faq/FA3751/can-i-automatically-answer-all-my-calls-with-video-in-skype-for-windows-desktop | ||||||
|  |     ''' | ||||||
|  |     package = 'com.skype.raider' | ||||||
|  |     min_apk_version = '7.01.0.669' | ||||||
|  |     view = [package + '/com.skype.android.app.calling.CallActivity', | ||||||
|  |             package + '/com.skype.android.app.calling.PreCallActivity', | ||||||
|  |             package + '/com.skype.android.app.chat.ChatActivity', | ||||||
|  |             package + '/com.skype.android.app.main.HubActivity', | ||||||
|  |             package + '/com.skype.android.app.main.SplashActivity', | ||||||
|  |             package + '/com.skype.android.app.signin.SignInActivity', | ||||||
|  |             package + '/com.skype.android.app.signin.UnifiedLandingPageActivity'] | ||||||
|  |  | ||||||
|  |     activity = ''  # Skype has no default 'main' activity | ||||||
|  |     launch_main = False  # overrides extended class | ||||||
|  |  | ||||||
|  |     parameters = [ | ||||||
|  |         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_name', kind=str, mandatory=True, default='Echo / Sound Test Service', | ||||||
|  |                   description='This is the contact display name as it appears in the people list'), | ||||||
|  |         Parameter('duration', kind=int, default=10, | ||||||
|  |                   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 call (default) or video'), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     # This workload relies on the internet so check that there is a working | ||||||
|  |     # internet connection | ||||||
|  |     requires_network = True | ||||||
|  |  | ||||||
|  |     def __init__(self, device, **kwargs): | ||||||
|  |         super(Skype, self).__init__(device, **kwargs) | ||||||
|  |         self.run_timeout = self.duration + 240 | ||||||
|  |  | ||||||
|  |     def validate(self): | ||||||
|  |         super(Skype, self).validate() | ||||||
|  |         self.uiauto_params['my_id'] = self.login_name | ||||||
|  |         self.uiauto_params['my_pwd'] = self.login_pass | ||||||
|  |         self.uiauto_params['name'] = self.contact_name.replace(' ', '0space0') | ||||||
|  |         self.uiauto_params['duration'] = self.duration | ||||||
|  |         self.uiauto_params['action'] = self.action | ||||||
|  |  | ||||||
|  |     def setup(self, context): | ||||||
|  |         super(Skype, self).setup(context) | ||||||
|  |         self.device.execute('am start -W -a android.intent.action.VIEW -d skype:dummy?dummy') | ||||||
							
								
								
									
										
											BIN
										
									
								
								wlauto/workloads/skype/com.arm.wlauto.uiauto.skype.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								wlauto/workloads/skype/com.arm.wlauto.uiauto.skype.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										39
									
								
								wlauto/workloads/skype/uiauto/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								wlauto/workloads/skype/uiauto/build.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | # CD into build dir if possible - allows building from any directory | ||||||
|  | script_path='.' | ||||||
|  | if `readlink -f $0 &>/dev/null`; then | ||||||
|  |     script_path=`readlink -f $0 2>/dev/null` | ||||||
|  | fi | ||||||
|  | script_dir=`dirname $script_path` | ||||||
|  | cd $script_dir | ||||||
|  |  | ||||||
|  | # Ensure build.xml exists before starting | ||||||
|  | if [[ ! -f build.xml ]]; then | ||||||
|  |     echo 'Ant build.xml file not found! Check that you are in the right directory.' | ||||||
|  |     exit 9 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Copy base classes from wlauto dist | ||||||
|  | class_dir=bin/classes/com/arm/wlauto/uiauto | ||||||
|  | base_classes=`python -c "import os, wlauto; print os.path.join(os.path.dirname(wlauto.__file__), 'common', 'android', '*.class')"` | ||||||
|  | mkdir -p $class_dir | ||||||
|  | cp $base_classes $class_dir | ||||||
|  |  | ||||||
|  | # Build and return appropriate exit code if failed | ||||||
|  | ant build | ||||||
|  | exit_code=$? | ||||||
|  | if [[ $exit_code -ne 0 ]]; then | ||||||
|  |     echo "ERROR: 'ant build' exited with code $exit_code" | ||||||
|  |     exit $exit_code | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # If successful move JAR file to workload folder (overwrite previous) | ||||||
|  | package=com.arm.wlauto.uiauto.skype.jar | ||||||
|  | rm -f ../$package | ||||||
|  | if [[ -f bin/$package ]]; then | ||||||
|  |     cp bin/$package .. | ||||||
|  | else | ||||||
|  |     echo 'ERROR: UiAutomator JAR could not be found!' | ||||||
|  |     exit 9 | ||||||
|  | fi | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project name="com.arm.wlauto.uiauto.skypevideo" default="help"> | <project name="com.arm.wlauto.uiauto.skype" default="help"> | ||||||
| 
 | 
 | ||||||
|     <!-- The local.properties file is created and updated by the 'android' tool. |     <!-- The local.properties file is created and updated by the 'android' tool. | ||||||
|          It contains the path to the SDK. It should *NOT* be checked into |          It contains the path to the SDK. It should *NOT* be checked into | ||||||
| @@ -0,0 +1,183 @@ | |||||||
|  | /*    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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package com.arm.wlauto.uiauto.skype; | ||||||
|  |  | ||||||
|  | import android.os.Bundle; | ||||||
|  |  | ||||||
|  | // Import the uiautomator libraries | ||||||
|  | import com.android.uiautomator.core.UiObject; | ||||||
|  | import com.android.uiautomator.core.UiObjectNotFoundException; | ||||||
|  | import com.android.uiautomator.core.UiSelector; | ||||||
|  | import com.android.uiautomator.core.UiWatcher; | ||||||
|  | import com.arm.wlauto.uiauto.UxPerfUiAutomation; | ||||||
|  |  | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
|  | public class UiAutomation extends UxPerfUiAutomation { | ||||||
|  |  | ||||||
|  |     public static final String TEXT_VIEW = "android.widget.TextView"; | ||||||
|  |  | ||||||
|  |     public Bundle parameters; | ||||||
|  |     public String packageName; | ||||||
|  |     public String packageID; | ||||||
|  |  | ||||||
|  |     // Creates a watcher for when a pop up dialog appears with a dismiss button. | ||||||
|  |     private UiWatcher createInfoPopUpWatcher() throws Exception { | ||||||
|  |         UiWatcher infoPopUpWatcher = new UiWatcher() { | ||||||
|  |             @Override | ||||||
|  |             public boolean checkForCondition() { | ||||||
|  |                 UiObject dismissButton = | ||||||
|  |                     new UiObject(new UiSelector().resourceId(packageID + "dismiss_button")); | ||||||
|  |  | ||||||
|  |                 if (dismissButton.exists()) { | ||||||
|  |                     try { | ||||||
|  |                         dismissButton.click(); | ||||||
|  |                     } catch (UiObjectNotFoundException e) { | ||||||
|  |                         e.printStackTrace(); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     Long viewTimeout = TimeUnit.SECONDS.toMillis(10); | ||||||
|  |                     boolean dismissed = dismissButton.waitUntilGone(viewTimeout); | ||||||
|  |  | ||||||
|  |                     return dismissed; | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         return infoPopUpWatcher; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void runUiAutomation() throws Exception { | ||||||
|  |         // Override superclass value | ||||||
|  |         this.uiAutoTimeout = TimeUnit.SECONDS.toMillis(10); | ||||||
|  |  | ||||||
|  |         // Get Params | ||||||
|  |         parameters = getParams(); | ||||||
|  |         packageName = parameters.getString("package"); | ||||||
|  |         packageID = packageName + ":id/"; | ||||||
|  |         String loginName = parameters.getString("my_id"); | ||||||
|  |         String loginPass = parameters.getString("my_pwd"); | ||||||
|  |         String contactName = parameters.getString("name").replace("0space0", " "); | ||||||
|  |         int callDuration = Integer.parseInt(parameters.getString("duration")); | ||||||
|  |         String callType = parameters.getString("action"); | ||||||
|  |         String resultsFile = parameters.getString("results_file"); | ||||||
|  |  | ||||||
|  |         setScreenOrientation(ScreenOrientation.NATURAL); | ||||||
|  |  | ||||||
|  |         UiWatcher infoPopUpWatcher = createInfoPopUpWatcher(); | ||||||
|  |         registerWatcher("infoPopUpWatcher", infoPopUpWatcher); | ||||||
|  |         runWatchers(); | ||||||
|  |  | ||||||
|  |         // Run tests | ||||||
|  |         handleLoginScreen(loginName, loginPass); | ||||||
|  |         searchForContact(contactName); | ||||||
|  |  | ||||||
|  |         if ("video".equalsIgnoreCase(callType)) { | ||||||
|  |             videoCallTest(callDuration); | ||||||
|  |         } else if ("voice".equalsIgnoreCase(callType)) { | ||||||
|  |             voiceCallTest(callDuration); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         removeWatcher("infoPopUpWatcher"); | ||||||
|  |         unsetScreenOrientation(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void handleLoginScreen(String username, String password) throws Exception { | ||||||
|  |         String useridResoureId = packageID + "sign_in_userid"; | ||||||
|  |         String nextButtonResourceId = packageID + "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 passwordResoureId = packageID + "signin_password"; | ||||||
|  |         String signinButtonResourceId = packageID + "sign_in_btn"; | ||||||
|  |         UiObject passwordField = new UiObject(new UiSelector().resourceId(passwordResoureId)); | ||||||
|  |         UiObject signinButton = new UiObject(new UiSelector().resourceId(signinButtonResourceId)); | ||||||
|  |         passwordField.setText(password); | ||||||
|  |         signinButton.clickAndWaitForNewWindow(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void searchForContact(String name) throws Exception { | ||||||
|  |         UiObject menuSearch = new UiObject(new UiSelector().resourceId(packageID + "menu_search")); | ||||||
|  |         boolean sharingResource = false; | ||||||
|  |  | ||||||
|  |         // If searching for a contact from Skype directly we need | ||||||
|  |         // to click the menu search button to display the contact search box. | ||||||
|  |         if (menuSearch.waitForExists(uiAutoTimeout)) { | ||||||
|  |             menuSearch.click(); | ||||||
|  |  | ||||||
|  |         // If sharing a resource from another app the contact search box is shown | ||||||
|  |         // by default. | ||||||
|  |         } else { | ||||||
|  |             sharingResource = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         UiObject search = getUiObjectByText("Search", "android.widget.EditText"); | ||||||
|  |         search.setText(name); | ||||||
|  |  | ||||||
|  |         UiObject peopleItem = getUiObjectByText(name, "android.widget.TextView"); | ||||||
|  |  | ||||||
|  |         peopleItem.waitForExists(uiAutoTimeout); | ||||||
|  |         peopleItem.click(); | ||||||
|  |  | ||||||
|  |         UiObject avatarPresence = | ||||||
|  |             new UiObject(new UiSelector().resourceId(packageID + "skype_avatar_presence")); | ||||||
|  |  | ||||||
|  |         // On some devices two clicks are needed to select a contact. | ||||||
|  |         if (!avatarPresence.waitUntilGone(uiAutoTimeout)) { | ||||||
|  |             peopleItem.click(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Before sharing a resource from another app we first need to | ||||||
|  |         // confirm our selection. | ||||||
|  |         if (sharingResource) { | ||||||
|  |             UiObject confirm = | ||||||
|  |                 new UiObject(new UiSelector().resourceId(packageID + "fab")); | ||||||
|  |             confirm.click(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void voiceCallTest(int duration) throws Exception { | ||||||
|  |         String testTag = "call_voice"; | ||||||
|  |         ActionLogger logger = new ActionLogger(testTag, parameters); | ||||||
|  |  | ||||||
|  |         logger.start(); | ||||||
|  |         makeCall(duration, false, testTag); | ||||||
|  |         logger.stop(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void videoCallTest(int duration) throws Exception { | ||||||
|  |         String testTag = "call_video"; | ||||||
|  |         ActionLogger logger = new ActionLogger(testTag, parameters); | ||||||
|  |  | ||||||
|  |         logger.start(); | ||||||
|  |         makeCall(duration, true, testTag); | ||||||
|  |         logger.stop(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void makeCall(int duration, boolean video, String testTag) throws Exception { | ||||||
|  |         String description = video ? "Video call" : "Call options"; | ||||||
|  |  | ||||||
|  |         UiObject callButton = new UiObject(new UiSelector().descriptionContains(description)); | ||||||
|  |         callButton.clickAndWaitForNewWindow(); | ||||||
|  |  | ||||||
|  |         UiObject muteButton = new UiObject(new UiSelector().descriptionContains("Mute")); | ||||||
|  |         muteButton.click(); | ||||||
|  |         sleep(duration); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,130 +0,0 @@ | |||||||
| #    Copyright 2014-2015 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. |  | ||||||
| # |  | ||||||
|  |  | ||||||
| # pylint: disable=E1101,W0201,E0203 |  | ||||||
|  |  | ||||||
| import time |  | ||||||
|  |  | ||||||
| from wlauto import UiAutomatorWorkload, Parameter |  | ||||||
| from wlauto.utils.types import boolean |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SkypeVideo(UiAutomatorWorkload): |  | ||||||
|  |  | ||||||
|     name = 'skypevideo' |  | ||||||
|     description = """ |  | ||||||
|     Initiates Skype video call to a specified contact for a pre-determined duration. |  | ||||||
|     (Note: requires Skype to be set up appropriately). |  | ||||||
|  |  | ||||||
|     This workload is intended for monitoring the behaviour of a device while a Skype |  | ||||||
|     video call is in progress (a common use case). It does not produce any score or |  | ||||||
|     metric and the intention is that some addition instrumentation is enabled while |  | ||||||
|     running this workload. |  | ||||||
|  |  | ||||||
|     This workload, obviously, requires a network connection (ideally, wifi). |  | ||||||
|  |  | ||||||
|     This workload accepts the following parameters: |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     **Skype Setup** |  | ||||||
|  |  | ||||||
|        - You should install Skype client from Google Play Store on the device |  | ||||||
|          (this was tested with client version 4.5.0.39600; other recent versions |  | ||||||
|          should also work). |  | ||||||
|        - You must have an account set up and logged into Skype on the device. |  | ||||||
|        - The contact to be called must be added (and has accepted) to the |  | ||||||
|          account. It's possible to have multiple contacts in the list, however |  | ||||||
|          the contact to be called *must* be visible on initial navigation to the |  | ||||||
|          list. |  | ||||||
|        - The contact must be able to received the call. This means that there |  | ||||||
|          must be  a Skype client running (somewhere) with the contact logged in |  | ||||||
|          and that client must have been configured to auto-accept calls from the |  | ||||||
|          account on the device (how to set this varies between different versions |  | ||||||
|          of Skype and between platforms -- please search online for specific |  | ||||||
|          instructions). |  | ||||||
|          https://support.skype.com/en/faq/FA3751/can-i-automatically-answer-all-my-calls-with-video-in-skype-for-windows-desktop |  | ||||||
|  |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     package = 'com.skype.raider' |  | ||||||
|  |  | ||||||
|     parameters = [ |  | ||||||
|         Parameter('duration', kind=int, default=300, |  | ||||||
|                   description='Duration of the video call in seconds.'), |  | ||||||
|         Parameter('contact', mandatory=True, |  | ||||||
|                   description=""" |  | ||||||
|                   The name of the Skype contact to call. The contact must be already |  | ||||||
|                   added (see below). *If use_gui is set*, then this must be the skype |  | ||||||
|                   ID of the contact, *otherwise*, this must be the name of the |  | ||||||
|                   contact as it appears in Skype client's contacts list. In the latter case |  | ||||||
|                   it *must not* contain underscore characters (``_``); it may, however, contain |  | ||||||
|                   spaces. There is no default, you **must specify the name of the contact**. |  | ||||||
|  |  | ||||||
|                   .. note:: You may alternatively specify the contact name as |  | ||||||
|                             ``skype_contact`` setting in your ``config.py``. If this is |  | ||||||
|                             specified, the ``contact`` parameter is optional, though |  | ||||||
|                             it may still be specified (in which case it will override |  | ||||||
|                             ``skype_contact`` setting). |  | ||||||
|                   """), |  | ||||||
|         Parameter('use_gui', kind=boolean, default=False, |  | ||||||
|                   description=""" |  | ||||||
|                   Specifies whether the call should be placed directly through a |  | ||||||
|                   Skype URI, or by navigating the GUI. The URI is the recommended way |  | ||||||
|                   to place Skype calls on a device, but that does not seem to work |  | ||||||
|                   correctly on some devices (the URI seems to just start Skype, but not |  | ||||||
|                   place the call), so an alternative exists that will start the Skype app |  | ||||||
|                   and will then navigate the UI to place the call (incidentally, this method |  | ||||||
|                   does not seem to work on all devices either, as sometimes Skype starts |  | ||||||
|                   backgrounded...). Please note that the meaning of ``contact`` prameter |  | ||||||
|                   is different depending on whether this is set.  Defaults to ``False``. |  | ||||||
|  |  | ||||||
|                   .. note:: You may alternatively specify this as ``skype_use_gui`` setting |  | ||||||
|                             in your ``config.py``. |  | ||||||
|                   """), |  | ||||||
|  |  | ||||||
|     ] |  | ||||||
|  |  | ||||||
|     def __init__(self, device, **kwargs): |  | ||||||
|         super(SkypeVideo, self).__init__(device, **kwargs) |  | ||||||
|         if self.use_gui: |  | ||||||
|             self.uiauto_params['name'] = self.contact.replace(' ', '_') |  | ||||||
|             self.uiauto_params['duration'] = self.duration |  | ||||||
|         self.run_timeout = self.duration + 30 |  | ||||||
|  |  | ||||||
|     def setup(self, context): |  | ||||||
|         if self.use_gui: |  | ||||||
|             super(SkypeVideo, 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:') |  | ||||||
|         else: |  | ||||||
|             self.device.execute('am force-stop {}'.format(self.package)) |  | ||||||
|  |  | ||||||
|     def run(self, context): |  | ||||||
|         if self.use_gui: |  | ||||||
|             super(SkypeVideo, self).run(context) |  | ||||||
|         else: |  | ||||||
|             command = "am start -W -a android.intent.action.VIEW -d \"skype:{}?call&video=true\"" |  | ||||||
|             self.logger.debug(self.device.execute(command.format(self.contact))) |  | ||||||
|             self.logger.debug('Call started; waiting for {} seconds...'.format(self.duration)) |  | ||||||
|             time.sleep(self.duration) |  | ||||||
|             self.device.execute('am force-stop com.skype.raider') |  | ||||||
|  |  | ||||||
|     def update_result(self, context): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     def teardown(self, context): |  | ||||||
|         if self.use_gui: |  | ||||||
|             super(SkypeVideo, self).teardown(context) |  | ||||||
|         self.device.execute('am force-stop {}'.format(self.package)) |  | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,28 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
| #    Copyright 2014-2015 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. |  | ||||||
| # |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 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', 'BaseUiAutomation.class')"` |  | ||||||
| mkdir -p $class_dir |  | ||||||
| cp $base_class $class_dir |  | ||||||
|  |  | ||||||
| ant build |  | ||||||
|  |  | ||||||
| if [[ -f bin/com.arm.wlauto.uiauto.skypevideo.jar ]]; then |  | ||||||
|     cp bin/com.arm.wlauto.uiauto.skypevideo.jar .. |  | ||||||
| fi |  | ||||||
| @@ -1,72 +0,0 @@ | |||||||
| /*    Copyright 2014-2015 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. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| package com.arm.wlauto.uiauto.skypevideo; |  | ||||||
|  |  | ||||||
| import android.app.Activity; |  | ||||||
| import android.os.Bundle; |  | ||||||
| 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 = "skypevideo"; |  | ||||||
|     public static String videoCallButtonResourceId = "com.skype.raider:id/chat_menu_item_call_video"; |  | ||||||
|     public static String noContactMessage = "Could not find contact \"%s\" in the contacts list."; |  | ||||||
|  |  | ||||||
|     public void runUiAutomation() throws Exception { |  | ||||||
|             Bundle parameters = getParams(); |  | ||||||
|             String contactName = parameters.getString("name").replace('_', ' '); |  | ||||||
|             int duration = Integer.parseInt(parameters.getString("duration")); |  | ||||||
|  |  | ||||||
|             selectContact(contactName); |  | ||||||
|             initiateCall(duration); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void selectContact(String name) throws Exception { |  | ||||||
|             UiSelector selector = new UiSelector(); |  | ||||||
|             UiObject peopleTab = new UiObject(selector.text("People")); |  | ||||||
|             peopleTab.click(); |  | ||||||
|             sleep(1);  // tab transition |  | ||||||
|  |  | ||||||
|             // Note: this assumes that the contact is in view and does not attempt to scroll to find it. |  | ||||||
|             // The expectation is that this automation will be used with a dedicated account that was set  |  | ||||||
|             // up for the purpose and so would only have the intended target plus one or two other contacts  |  | ||||||
|             // at most  in the list. If that is not the case, then this needs to be re-written to scroll to  |  | ||||||
|             // find the contact if necessary. |  | ||||||
|             UiObject contactCard = new UiObject(selector.text(name)); |  | ||||||
|             if (!contactCard.exists()) { |  | ||||||
|                     throw new UiObjectNotFoundException(String.format(noContactMessage, name)); |  | ||||||
|             } |  | ||||||
|             contactCard.clickAndWaitForNewWindow(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void initiateCall(int duration) throws Exception { |  | ||||||
|             UiSelector selector = new UiSelector(); |  | ||||||
|             UiObject videoCallButton = new UiObject(selector.resourceId(videoCallButtonResourceId)); |  | ||||||
|             videoCallButton.click(); |  | ||||||
|             sleep(duration); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user