1#!/usr/bin/env python3 2# 3# Copyright 2016 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# This is test util for subscription setup. 18# It will be deleted once we have better solution for subscription ids. 19from future import standard_library 20standard_library.install_aliases() 21from acts_contrib.test_utils.tel.tel_defines import CHIPSET_MODELS_LIST 22from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID 23from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID 24from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION 25 26import time 27 28 29def initial_set_up_for_subid_infomation(log, ad): 30 """Initial subid setup for voice, message and data according to ad's 31 attribute. 32 33 Setup sub id properties for android device. Including the followings: 34 incoming_voice_sub_id 35 incoming_message_sub_id 36 outgoing_voice_sub_id 37 outgoing_message_sub_id 38 default_data_sub_id 39 40 Args: 41 log: log object 42 ad: android device object 43 44 Returns: 45 None 46 """ 47 # outgoing_voice_sub_id 48 # If default_voice_sim_slot_index is set in config file, then use sub_id 49 # of this SIM as default_outgoing_sub_id. If default_voice_sim_slot_index 50 # is not set, then use default voice sub_id as default_outgoing_sub_id. 51 # Outgoing voice call will be made on default_outgoing_sub_id by default. 52 if hasattr(ad, "default_voice_sim_slot_index"): 53 outgoing_voice_sub_id = get_subid_from_slot_index( 54 log, ad, ad.default_voice_sim_slot_index) 55 set_subid_for_outgoing_call(ad, outgoing_voice_sub_id) 56 else: 57 outgoing_voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 58 setattr(ad, "outgoing_voice_sub_id", outgoing_voice_sub_id) 59 60 # outgoing_message_sub_id 61 # If default_message_sim_slot_index is set in config file, then use sub_id 62 # of this SIM as outgoing_message_sub_id. If default_message_sim_slot_index 63 # is not set, then use default Sms sub_id as outgoing_message_sub_id. 64 # Outgoing SMS will be sent on outgoing_message_sub_id by default. 65 if hasattr(ad, "default_message_sim_slot_index"): 66 outgoing_message_sub_id = get_subid_from_slot_index( 67 log, ad, ad.default_message_sim_slot_index) 68 set_subid_for_message(ad, outgoing_message_sub_id) 69 else: 70 outgoing_message_sub_id = ad.droid.subscriptionGetDefaultSmsSubId() 71 setattr(ad, "outgoing_message_sub_id", outgoing_message_sub_id) 72 73 # default_data_sub_id 74 # If default_data_sim_slot_index is set in config file, then use sub_id 75 # of this SIM as default_data_sub_id. If default_data_sim_slot_index 76 # is not set, then use default Data sub_id as default_data_sub_id. 77 # Data connection will be established on default_data_sub_id by default. 78 if hasattr(ad, "default_data_sim_slot_index"): 79 default_data_sub_id = get_subid_from_slot_index( 80 log, ad, ad.default_data_sim_slot_index) 81 set_subid_for_data(ad, default_data_sub_id, 0) 82 else: 83 default_data_sub_id = ad.droid.subscriptionGetDefaultDataSubId() 84 setattr(ad, "default_data_sub_id", default_data_sub_id) 85 86 # This is for Incoming Voice Sub ID 87 # If "incoming_voice_sim_slot_index" is set in config file, then 88 # incoming voice call will call to the phone number of the SIM in 89 # "incoming_voice_sim_slot_index". 90 # If "incoming_voice_sim_slot_index" is NOT set in config file, 91 # then incoming voice call will call to the phone number of default 92 # subId. 93 if hasattr(ad, "incoming_voice_sim_slot_index"): 94 incoming_voice_sub_id = get_subid_from_slot_index( 95 log, ad, ad.incoming_voice_sim_slot_index) 96 else: 97 incoming_voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 98 setattr(ad, "incoming_voice_sub_id", incoming_voice_sub_id) 99 100 # This is for Incoming SMS Sub ID 101 # If "incoming_message_sim_slot_index" is set in config file, then 102 # incoming SMS be sent to the phone number of the SIM in 103 # "incoming_message_sim_slot_index". 104 # If "incoming_message_sim_slot_index" is NOT set in config file, 105 # then incoming SMS be sent to the phone number of default 106 # subId. 107 if hasattr(ad, "incoming_message_sim_slot_index"): 108 incoming_message_sub_id = get_subid_from_slot_index( 109 log, ad, ad.incoming_message_sim_slot_index) 110 else: 111 incoming_message_sub_id = ad.droid.subscriptionGetDefaultSmsSubId() 112 setattr(ad, "incoming_message_sub_id", incoming_message_sub_id) 113 114 115def get_default_data_sub_id(ad): 116 """ Get default data subscription id 117 """ 118 if hasattr(ad, "default_data_sub_id"): 119 return ad.default_data_sub_id 120 else: 121 return ad.droid.subscriptionGetDefaultDataSubId() 122 123 124def get_outgoing_message_sub_id(ad): 125 """ Get outgoing message subscription id 126 """ 127 if hasattr(ad, "outgoing_message_sub_id"): 128 return ad.outgoing_message_sub_id 129 else: 130 return ad.droid.subscriptionGetDefaultSmsSubId() 131 132 133def get_outgoing_voice_sub_id(ad): 134 """ Get outgoing voice subscription id 135 """ 136 if hasattr(ad, "outgoing_voice_sub_id"): 137 return ad.outgoing_voice_sub_id 138 else: 139 return ad.droid.subscriptionGetDefaultVoiceSubId() 140 141 142def get_incoming_voice_sub_id(ad): 143 """ Get incoming voice subscription id 144 """ 145 if hasattr(ad, "incoming_voice_sub_id"): 146 return ad.incoming_voice_sub_id 147 else: 148 return ad.droid.subscriptionGetDefaultVoiceSubId() 149 150 151def get_incoming_message_sub_id(ad): 152 """ Get incoming message subscription id 153 """ 154 if hasattr(ad, "incoming_message_sub_id"): 155 return ad.incoming_message_sub_id 156 else: 157 return ad.droid.subscriptionGetDefaultSmsSubId() 158 159 160def get_subid_from_slot_index(log, ad, sim_slot_index): 161 """ Get the subscription ID for a SIM at a particular slot 162 163 Args: 164 ad: android_device object. 165 166 Returns: 167 result: Subscription ID 168 """ 169 subInfo = ad.droid.subscriptionGetAllSubInfoList() 170 for info in subInfo: 171 if info['simSlotIndex'] == sim_slot_index: 172 return info['subscriptionId'] 173 return INVALID_SUB_ID 174 175 176def get_operatorname_from_slot_index(ad, sim_slot_index): 177 """ Get the operator name for a SIM at a particular slot 178 179 Args: 180 ad: android_device object. 181 182 Returns: 183 result: Operator Name 184 """ 185 subInfo = ad.droid.subscriptionGetAllSubInfoList() 186 for info in subInfo: 187 if info['simSlotIndex'] == sim_slot_index: 188 return info['displayName'] 189 return None 190 191 192def get_carrierid_from_slot_index(ad, sim_slot_index): 193 """ Get the carrierId for a SIM at a particular slot 194 195 Args: 196 ad: android_device object. 197 sim_slot_index: slot 0 or slot 1 198 199 Returns: 200 result: CarrierId 201 """ 202 subInfo = ad.droid.subscriptionGetAllSubInfoList() 203 for info in subInfo: 204 if info['simSlotIndex'] == sim_slot_index: 205 return info['carrierId'] 206 return None 207 208def get_isopportunistic_from_slot_index(ad, sim_slot_index): 209 """ Get the isOppotunistic field for a particular slot 210 211 Args: 212 ad: android_device object. 213 sim_slot_index: slot 0 or slot 1 214 215 Returns: 216 result: True or False based on Value set 217 """ 218 subInfo = ad.droid.subscriptionGetAllSubInfoList() 219 for info in subInfo: 220 if info['simSlotIndex'] == sim_slot_index: 221 return info['isOpportunistic'] 222 return None 223 224def set_subid_for_data(ad, sub_id, time_to_sleep=WAIT_TIME_CHANGE_DATA_SUB_ID): 225 """Set subId for data 226 227 Args: 228 ad: android device object. 229 sub_id: subscription id (integer) 230 231 Returns: 232 None 233 """ 234 # TODO: Need to check onSubscriptionChanged event. b/27843365 235 if ad.droid.subscriptionGetDefaultDataSubId() != sub_id: 236 ad.droid.subscriptionSetDefaultDataSubId(sub_id) 237 time.sleep(time_to_sleep) 238 setattr(ad, "default_data_sub_id", sub_id) 239 240 241def set_subid_for_message(ad, sub_id): 242 """Set subId for outgoing message 243 244 Args: 245 ad: android device object. 246 sub_id: subscription id (integer) 247 248 Returns: 249 None 250 """ 251 ad.droid.subscriptionSetDefaultSmsSubId(sub_id) 252 if hasattr(ad, "outgoing_message_sub_id"): 253 ad.outgoing_message_sub_id = sub_id 254 255 256def set_message_subid(ad, sub_id): 257 """Set subId for both outgoing and incoming messages 258 259 Args: 260 ad: android device object. 261 sub_id: subscription id (integer) 262 263 Returns: 264 None 265 """ 266 ad.droid.subscriptionSetDefaultSmsSubId(sub_id) 267 if hasattr(ad, "outgoing_message_sub_id"): 268 ad.outgoing_message_sub_id = sub_id 269 if hasattr(ad, "incoming_message_sub_id"): 270 ad.incoming_message_sub_id = sub_id 271 272 273def set_subid_for_outgoing_call(ad, sub_id): 274 """Set subId for outgoing voice call 275 276 Args: 277 ad: android device object. 278 sub_id: subscription id (integer) 279 280 Returns: 281 None 282 """ 283 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id) 284 if hasattr(ad, "outgoing_voice_sub_id"): 285 ad.outgoing_voice_sub_id = sub_id 286 287 288def set_incoming_voice_sub_id(ad, sub_id): 289 """Set default subId for voice calls 290 291 Args: 292 ad: android device object. 293 sub_id: subscription id (integer) 294 295 Returns: 296 None 297 """ 298 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 299 if hasattr(ad, "incoming_voice_sub_id"): 300 ad.incoming_voice_sub_id = sub_id 301 302 303def set_voice_sub_id(ad, sub_id): 304 """Set default subId for both incoming and outgoing voice calls 305 306 Args: 307 ad: android device object. 308 sub_id: subscription id (integer) 309 310 Returns: 311 None 312 """ 313 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 314 if hasattr(ad, "incoming_voice_sub_id"): 315 ad.incoming_voice_sub_id = sub_id 316 if hasattr(ad, "outgoing_voice_sub_id"): 317 ad.outgoing_voice_sub_id = sub_id 318 319 320def set_voice_sub_id(ad, sub_id): 321 """Set default subId for both incoming and outgoing voice calls 322 323 Args: 324 ad: android device object. 325 sub_id: subscription id (integer) 326 327 Returns: 328 None 329 """ 330 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 331 if hasattr(ad, "incoming_voice_sub_id"): 332 ad.incoming_voice_sub_id = sub_id 333 if hasattr(ad, "outgoing_voice_sub_id"): 334 ad.outgoing_voice_sub_id = sub_id 335 336 337def set_default_sub_for_all_services(ad, slot_id=0): 338 """Set subId for all services 339 340 Args: 341 ad: android device object. 342 slot_id: 0 or 1 (integer) 343 344 Returns: 345 None 346 """ 347 sub_id = get_subid_from_slot_index(ad.log, ad, slot_id) 348 ad.log.info("Default Subid for all service is %s", sub_id) 349 set_subid_for_outgoing_call(ad, sub_id) 350 set_incoming_voice_sub_id(ad, sub_id) 351 set_subid_for_data(ad, sub_id) 352 set_subid_for_message(ad, sub_id) 353 ad.droid.telephonyToggleDataConnection(True) 354 355 356def perform_dds_switch(ad): 357 slot_dict = {0: {}, 1: {}} 358 for slot in (0,1): 359 slot_dict[slot]['sub_id'] = get_subid_from_slot_index(ad.log, ad, slot) 360 slot_dict[slot]['operator'] = get_operatorname_from_slot_index(ad, slot) 361 ad.log.debug("%s", slot_dict) 362 363 current_data = get_default_data_sub_id(ad) 364 if slot_dict[0]['sub_id'] == current_data: 365 ad.log.info("DDS Switch from %s to %s", slot_dict[0]['operator'], 366 slot_dict[1]['operator']) 367 new_data = slot_dict[1]['sub_id'] 368 new_oper = slot_dict[1]['operator'] 369 else: 370 ad.log.info("DDS Switch from %s to %s", slot_dict[1]['operator'], 371 slot_dict[0]['operator']) 372 new_data = slot_dict[0]['sub_id'] 373 new_oper = slot_dict[0]['operator'] 374 set_subid_for_data(ad, new_data) 375 ad.droid.telephonyToggleDataConnection(True) 376 if get_default_data_sub_id(ad) == new_data: 377 return new_oper 378 else: 379 ad.log.error("DDS Switch Failed") 380 return False 381 382 383def set_dds_on_slot_0(ad): 384 sub_id = get_subid_from_slot_index(ad.log, ad, 0) 385 if sub_id == INVALID_SUB_ID: 386 ad.log.warning("Invalid sub ID at slot 0") 387 return False 388 operator = get_operatorname_from_slot_index(ad, 0) 389 if get_default_data_sub_id(ad) == sub_id: 390 ad.log.info("Current DDS is already on %s", operator) 391 return True 392 ad.log.info("Setting DDS on %s", operator) 393 set_subid_for_data(ad, sub_id) 394 ad.droid.telephonyToggleDataConnection(True) 395 time.sleep(WAIT_TIME_CHANGE_DATA_SUB_ID) 396 if get_default_data_sub_id(ad) == sub_id: 397 return True 398 else: 399 return False 400 401 402def set_dds_on_slot_1(ad): 403 sub_id = get_subid_from_slot_index(ad.log, ad, 1) 404 if sub_id == INVALID_SUB_ID: 405 ad.log.warning("Invalid sub ID at slot 1") 406 return False 407 operator = get_operatorname_from_slot_index(ad, 1) 408 if get_default_data_sub_id(ad) == sub_id: 409 ad.log.info("Current DDS is already on %s", operator) 410 return True 411 ad.log.info("Setting DDS on %s", operator) 412 set_subid_for_data(ad, sub_id) 413 ad.droid.telephonyToggleDataConnection(True) 414 time.sleep(WAIT_TIME_CHANGE_DATA_SUB_ID) 415 if get_default_data_sub_id(ad) == sub_id: 416 return True 417 else: 418 return False 419 420 421def set_always_allow_mms_data(ad, sub_id, state=True): 422 """Set always allow mms data on sub_id 423 424 Args: 425 ad: android device object. 426 sub_id: subscription id (integer) 427 state: True or False 428 429 Returns: 430 None 431 """ 432 if any(model in ad.model for model in CHIPSET_MODELS_LIST): 433 ad.log.debug("SKIP telephonySetAlwaysAllowMmsData") 434 else: 435 ad.log.debug("telephonySetAlwaysAllowMmsData %s sub_id %s", state, sub_id) 436 ad.droid.telephonySetAlwaysAllowMmsData(sub_id, state) 437 return True 438 439 440def get_cbrs_and_default_sub_id(ad): 441 """Gets CBRS and Default SubId 442 443 Args: 444 ad: android device object. 445 446 Returns: 447 cbrs_subId 448 default_subId 449 """ 450 cbrs_subid, default_subid = None, None 451 slot_dict = {0: {}, 1: {}} 452 for slot in (0, 1): 453 slot_dict[slot]['sub_id'] = get_subid_from_slot_index( 454 ad.log, ad, slot) 455 slot_dict[slot]['carrier_id'] = get_carrierid_from_slot_index( 456 ad, slot) 457 slot_dict[slot]['operator'] = get_operatorname_from_slot_index( 458 ad, slot) 459 if slot_dict[slot]['carrier_id'] == 2340: 460 cbrs_subid = slot_dict[slot]['sub_id'] 461 else: 462 default_subid = slot_dict[slot]['sub_id'] 463 ad.log.info("Slot %d - Sub %s - Carrier %d - %s", slot, 464 slot_dict[slot]['sub_id'], 465 slot_dict[slot]['carrier_id'], 466 slot_dict[slot]['operator']) 467 if not cbrs_subid: 468 ad.log.error("CBRS sub_id is not ACTIVE") 469 return cbrs_subid, default_subid 470 471 472def get_subid_on_same_network_of_host_ad(ads, host_sub_id=None, type="voice"): 473 ad_host = ads[0] 474 ad_p1 = ads[1] 475 476 try: 477 ad_p2 = ads[2] 478 except: 479 ad_p2 = None 480 481 if not host_sub_id: 482 if type == "sms": 483 host_sub_id = get_outgoing_message_sub_id(ad_host) 484 else: 485 host_sub_id = get_incoming_voice_sub_id(ad_host) 486 host_mcc = ad_host.telephony["subscription"][host_sub_id]["mcc"] 487 host_mnc = ad_host.telephony["subscription"][host_sub_id]["mnc"] 488 p1_sub_id = INVALID_SUB_ID 489 p2_sub_id = INVALID_SUB_ID 490 p1_mcc = None 491 p1_mnc = None 492 p2_mcc = None 493 p2_mnc = None 494 495 for ad in [ad_p1, ad_p2]: 496 if ad: 497 for sub_id in ad.telephony["subscription"]: 498 mcc = ad.telephony["subscription"][sub_id]["mcc"] 499 mnc = ad.telephony["subscription"][sub_id]["mnc"] 500 501 if ad == ad_p1: 502 if p1_sub_id == INVALID_SUB_ID: 503 p1_sub_id = sub_id 504 if not p1_mcc: 505 p1_mcc = mcc 506 if not p1_mnc: 507 p1_mnc = mnc 508 elif ad == ad_p2: 509 if p2_sub_id == INVALID_SUB_ID: 510 p2_sub_id = sub_id 511 if not p2_mcc: 512 p2_mcc = mcc 513 if not p2_mnc: 514 p2_mnc = mnc 515 516 if mcc == host_mcc and mnc == host_mnc: 517 if ad == ad_p1: 518 p1_sub_id = sub_id 519 p1_mcc = mcc 520 p1_mnc = mnc 521 522 elif ad == ad_p2: 523 p2_sub_id = sub_id 524 p2_mcc = mcc 525 p2_mnc = mnc 526 527 return host_sub_id, p1_sub_id, p2_sub_id 528