From e921040a0261a516ba439219791409deb91827be Mon Sep 17 00:00:00 2001 From: Fahad Afroze <fafroze@google.com> Date: Thu, 15 Dec 2022 13:17:12 +0000 Subject: [PATCH] [PTS-Bot]: Added 7 OPP/SR test cases Added opp.py file Updated _android.proto and AndroidInternal.kt files Added AcceptIncomingFile function in AndroidInternal.kt using uiautomator. Test: atest pts-bot:OPP -v Change-Id: If2ab94f8033035ddf7b40a1a5acdc58b8f272acc --- android/pandora/mmi2grpc/mmi2grpc/__init__.py | 8 ++ android/pandora/mmi2grpc/mmi2grpc/opp.py | 118 ++++++++++++++++++ android/pandora/server/Android.bp | 1 + android/pandora/server/configs/PtsBotTest.xml | 1 + .../pandora/server/configs/PtsBotTestMts.xml | 1 + .../server/configs/pts_bot_tests_config.json | 16 +++ .../com/android/pandora/AndroidInternal.kt | 17 +++ .../pandora_experimental/_android.proto | 2 + 8 files changed, 164 insertions(+) create mode 100644 android/pandora/mmi2grpc/mmi2grpc/opp.py diff --git a/android/pandora/mmi2grpc/mmi2grpc/__init__.py b/android/pandora/mmi2grpc/mmi2grpc/__init__.py index 1047e458a06..97235237736 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/__init__.py +++ b/android/pandora/mmi2grpc/mmi2grpc/__init__.py @@ -31,6 +31,7 @@ from mmi2grpc.hid import HIDProxy from mmi2grpc.hogp import HOGPProxy from mmi2grpc.l2cap import L2CAPProxy from mmi2grpc.map import MAPProxy +from mmi2grpc.opp import OPPProxy from mmi2grpc.pbap import PBAPProxy from mmi2grpc.rfcomm import RFCOMMProxy from mmi2grpc.sdp import SDPProxy @@ -80,6 +81,7 @@ class IUT: self._hogp = None self._l2cap = None self._map = None + self._opp = None self._pbap = None self._rfcomm = None self._sdp = None @@ -113,6 +115,7 @@ class IUT: self._hid = None self._hogp = None self._map = None + self._opp = None self._pbap = None self._rfcomm = None self._sdp = None @@ -232,6 +235,11 @@ class IUT: if not self._map: self._map = MAPProxy(grpc.insecure_channel(f"localhost:{self.pandora_server_port}")) return self._map.interact(test, interaction, description, pts_address) + # Handles OPP MMIs. + if profile in ("OPP"): + if not self._opp: + self._opp = OPPProxy(grpc.insecure_channel(f"localhost:{self.pandora_server_port}")) + return self._opp.interact(test, interaction, description, pts_address) # Instantiates PBAP proxy and reroutes corresponding MMIs to it. if profile in ("PBAP"): if not self._pbap: diff --git a/android/pandora/mmi2grpc/mmi2grpc/opp.py b/android/pandora/mmi2grpc/mmi2grpc/opp.py new file mode 100644 index 00000000000..d74e5cf7ea9 --- /dev/null +++ b/android/pandora/mmi2grpc/mmi2grpc/opp.py @@ -0,0 +1,118 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. +"""OPP proxy module.""" + +from typing import Optional + +from mmi2grpc._helpers import assert_description +from mmi2grpc._proxy import ProfileProxy + +from pandora_experimental.host_grpc import Host +from pandora_experimental.host_pb2 import Connection +from pandora_experimental._android_grpc import Android +from pandora_experimental._android_pb2 import AccessType + + +class OPPProxy(ProfileProxy): + """OPP proxy. + + Implements OPP PTS MMIs. + """ + connection: Optional[Connection] = None + + def __init__(self, channel): + super().__init__(channel) + + self.host = Host(channel) + self._android = Android(channel) + + self.connection = None + + @assert_description + def TSC_OBEX_MMI_iut_accept_connect_OPP(self, pts_addr: bytes, **kwargs): + """ + Please accept the OBEX CONNECT REQ command for OPP. + """ + if self.connection is None: + self.connection = self.host.WaitConnection(address=pts_addr).connection + + return "OK" + + @assert_description + def TSC_OPP_mmi_user_action_remove_object(self, **kwargs): + """ + If necessary take action to remove any file(s) named 'BC_BV01.bmp' from + the IUT. + + Press 'OK' to confirm that the file is not present on the + IUT. + """ + + return "OK" + + @assert_description + def TSC_OBEX_MMI_iut_accept_put(self, **kwargs): + """ + Please accept the PUT REQUEST. + """ + self._android.AcceptIncomingFile() + + return "OK" + + @assert_description + def TSC_OPP_mmi_user_verify_does_object_exist(self, **kwargs): + """ + Does the IUT now contain the following files? + + BC_BV01.bmp + + Note: If + TSPX_supported_extension is not .bmp, the file content of the file will + not be formatted for the TSPX_supported extension, this is normal. + """ + + return "OK" + + @assert_description + def TSC_OBEX_MMI_iut_accept_slc_connect_l2cap(self, pts_addr: bytes, **kwargs): + """ + Please accept the l2cap channel connection for an OBEX connection. + """ + self.connection = self.host.WaitConnection(address=pts_addr).connection + + return "OK" + + @assert_description + def TSC_OBEX_MMI_iut_reject_action(self, **kwargs): + """ + Take action to reject the ACTION command sent by PTS. + """ + + return "OK" + + @assert_description + def TSC_OBEX_MMI_iut_accept_disconnect(self, **kwargs): + """ + Please accept the OBEX DISCONNECT REQ command. + """ + + return "OK" + + @assert_description + def TSC_OBEX_MMI_iut_accept_slc_disconnect(self, **kwargs): + """ + Please accept the disconnection of the transport channel. + """ + + return "OK" diff --git a/android/pandora/server/Android.bp b/android/pandora/server/Android.bp index 6598be3dd37..7eb0eeb0100 100644 --- a/android/pandora/server/Android.bp +++ b/android/pandora/server/Android.bp @@ -18,6 +18,7 @@ java_library_static { static_libs: [ "androidx.test.runner", "androidx.test.core", + "androidx.test.uiautomator_uiautomator", "grpc-java-netty-shaded-test", "grpc-java-lite", "guava", diff --git a/android/pandora/server/configs/PtsBotTest.xml b/android/pandora/server/configs/PtsBotTest.xml index b14f0ca9264..feb852421ee 100644 --- a/android/pandora/server/configs/PtsBotTest.xml +++ b/android/pandora/server/configs/PtsBotTest.xml @@ -43,6 +43,7 @@ <option name="profile" value="L2CAP/COS" /> <option name="profile" value="L2CAP/LE" /> <option name="profile" value="MAP" /> + <option name="profile" value="OPP" /> <option name="profile" value="PBAP/PSE" /> <option name="profile" value="RFCOMM" /> <option name="profile" value="SDP" /> diff --git a/android/pandora/server/configs/PtsBotTestMts.xml b/android/pandora/server/configs/PtsBotTestMts.xml index 179dda913cd..5df935cee22 100644 --- a/android/pandora/server/configs/PtsBotTestMts.xml +++ b/android/pandora/server/configs/PtsBotTestMts.xml @@ -43,6 +43,7 @@ <option name="profile" value="L2CAP/COS" /> <option name="profile" value="L2CAP/LE" /> <option name="profile" value="MAP" /> + <option name="profile" value="OPP" /> <option name="profile" value="PBAP/PSE" /> <option name="profile" value="RFCOMM" /> <option name="profile" value="SDP" /> diff --git a/android/pandora/server/configs/pts_bot_tests_config.json b/android/pandora/server/configs/pts_bot_tests_config.json index 69098c9583e..fdf6cad76c1 100644 --- a/android/pandora/server/configs/pts_bot_tests_config.json +++ b/android/pandora/server/configs/pts_bot_tests_config.json @@ -375,6 +375,13 @@ "MAP/MSE/MSM/BV-06-I", "MAP/MSE/MSM/BV-07-I", "MAP/MSE/MSM/BV-08-I", + "OPP/SR/GOEP/BC/BV-01-I", + "OPP/SR/GOEP/CON/BV-02-C", + "OPP/SR/GOEP/ROB/BV-01-C", + "OPP/SR/GOEP/SRM/BI-03-C", + "OPP/SR/OPH/BV-01-I", + "OPP/SR/OPH/BV-02-I", + "OPP/SR/OPH/BV-34-I", "PBAP/PSE/GOEP/BC/BV-03-I", "PBAP/PSE/GOEP/CON/BV-02-C", "PBAP/PSE/GOEP/ROB/BV-01-C", @@ -765,6 +772,15 @@ "MAP/MSE/MMN/BV-14-I", "MAP/MSE/MMU/BV-02-I", "PBAP/PSE/SSM/BV-07-C", + "OPP/CL/GOEP/BC/BV-02-I", + "OPP/CL/GOEP/CON/BV-01-C", + "OPP/CL/OPH/BV-01-I", + "OPP/CL/OPH/BV-34-I", + "OPP/SR/BCP/BV-02-I", + "OPP/SR/GOEP/ROB/BV-02-C", + "OPP/SR/OPH/BV-10-I", + "OPP/SR/OPH/BV-14-I", + "OPP/SR/OPH/BV-18-I", "RFCOMM/DEVA-DEVB/RFC/BV-21-C", "RFCOMM/DEVA-DEVB/RFC/BV-22-C", "SM/CEN/PKE/BV-01-C", diff --git a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt index 21b73d2897f..9b70fb00a2c 100644 --- a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt +++ b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt @@ -28,6 +28,10 @@ import android.net.Uri import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothManager +import androidx.test.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel @@ -40,10 +44,15 @@ private const val TAG = "PandoraAndroidInternal" class AndroidInternal(val context: Context) : AndroidImplBase() { private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default) + private val INCOMING_FILE_ACCEPT_BTN = "ACCEPT" + private val INCOMING_FILE_TITLE = "Incoming file" + private val INCOMING_FILE_WAIT_TIMEOUT = 2000L + private val bluetoothManager = context.getSystemService(BluetoothManager::class.java)!! private val bluetoothAdapter = bluetoothManager.adapter private var telephonyManager = context.getSystemService(TelephonyManager::class.java) private val DEFAULT_MESSAGE_LEN = 130 + private var device: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) fun deinit() { scope.cancel() @@ -80,4 +89,12 @@ class AndroidInternal(val context: Context) : AndroidImplBase() { Empty.getDefaultInstance() } } + + override fun acceptIncomingFile(request: Empty, responseObserver: StreamObserver<Empty>) { + grpcUnary<Empty>(scope, responseObserver) { + device.wait(Until.findObject(By.text(INCOMING_FILE_TITLE)), INCOMING_FILE_WAIT_TIMEOUT).click() + device.wait(Until.findObject(By.text(INCOMING_FILE_ACCEPT_BTN)), INCOMING_FILE_WAIT_TIMEOUT).click() + Empty.getDefaultInstance() + } + } } diff --git a/pandora/interfaces/pandora_experimental/_android.proto b/pandora/interfaces/pandora_experimental/_android.proto index 27960fc17f7..cda445ea84a 100644 --- a/pandora/interfaces/pandora_experimental/_android.proto +++ b/pandora/interfaces/pandora_experimental/_android.proto @@ -18,6 +18,8 @@ service Android { rpc SetAccessPermission(SetAccessPermissionRequest) returns (google.protobuf.Empty); // Send SMS rpc SendSMS(google.protobuf.Empty) returns (google.protobuf.Empty); + // Accept incoming file + rpc AcceptIncomingFile(google.protobuf.Empty) returns (google.protobuf.Empty); } message LogRequest { -- GitLab