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.test_utils.tel.tel_defines import INVALID_SUB_ID
22from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
23from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
24
25import time
26
27
28def initial_set_up_for_subid_infomation(log, ad):
29    """Initial subid setup for voice, message and data according to ad's
30    attribute.
31
32    Setup sub id properties for android device. Including the followings:
33        incoming_voice_sub_id
34        incoming_message_sub_id
35        outgoing_voice_sub_id
36        outgoing_message_sub_id
37        default_data_sub_id
38
39    Args:
40        log: log object
41        ad: android device object
42
43    Returns:
44        None
45    """
46    # outgoing_voice_sub_id
47    # If default_voice_sim_slot_index is set in config file, then use sub_id
48    # of this SIM as default_outgoing_sub_id. If default_voice_sim_slot_index
49    # is not set, then use default voice sub_id as default_outgoing_sub_id.
50    # Outgoing voice call will be made on default_outgoing_sub_id by default.
51    if hasattr(ad, "default_voice_sim_slot_index"):
52        outgoing_voice_sub_id = get_subid_from_slot_index(
53            log, ad, ad.default_voice_sim_slot_index)
54        set_subid_for_outgoing_call(ad, outgoing_voice_sub_id)
55    else:
56        outgoing_voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
57    setattr(ad, "outgoing_voice_sub_id", outgoing_voice_sub_id)
58
59    # outgoing_message_sub_id
60    # If default_message_sim_slot_index is set in config file, then use sub_id
61    # of this SIM as outgoing_message_sub_id. If default_message_sim_slot_index
62    # is not set, then use default Sms sub_id as outgoing_message_sub_id.
63    # Outgoing SMS will be sent on outgoing_message_sub_id by default.
64    if hasattr(ad, "default_message_sim_slot_index"):
65        outgoing_message_sub_id = get_subid_from_slot_index(
66            log, ad, ad.default_message_sim_slot_index)
67        set_subid_for_message(ad, outgoing_message_sub_id)
68    else:
69        outgoing_message_sub_id = ad.droid.subscriptionGetDefaultSmsSubId()
70    setattr(ad, "outgoing_message_sub_id", outgoing_message_sub_id)
71
72    # default_data_sub_id
73    # If default_data_sim_slot_index is set in config file, then use sub_id
74    # of this SIM as default_data_sub_id. If default_data_sim_slot_index
75    # is not set, then use default Data sub_id as default_data_sub_id.
76    # Data connection will be established on default_data_sub_id by default.
77    if hasattr(ad, "default_data_sim_slot_index"):
78        default_data_sub_id = get_subid_from_slot_index(
79            log, ad, ad.default_data_sim_slot_index)
80        set_subid_for_data(ad, default_data_sub_id, 0)
81    else:
82        default_data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
83    setattr(ad, "default_data_sub_id", default_data_sub_id)
84
85    # This is for Incoming Voice Sub ID
86    # If "incoming_voice_sim_slot_index" is set in config file, then
87    # incoming voice call will call to the phone number of the SIM in
88    # "incoming_voice_sim_slot_index".
89    # If "incoming_voice_sim_slot_index" is NOT set in config file,
90    # then incoming voice call will call to the phone number of default
91    # subId.
92    if hasattr(ad, "incoming_voice_sim_slot_index"):
93        incoming_voice_sub_id = get_subid_from_slot_index(
94            log, ad, ad.incoming_voice_sim_slot_index)
95    else:
96        incoming_voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
97    setattr(ad, "incoming_voice_sub_id", incoming_voice_sub_id)
98
99    # This is for Incoming SMS Sub ID
100    # If "incoming_message_sim_slot_index" is set in config file, then
101    # incoming SMS be sent to the phone number of the SIM in
102    # "incoming_message_sim_slot_index".
103    # If "incoming_message_sim_slot_index" is NOT set in config file,
104    # then incoming SMS be sent to the phone number of default
105    # subId.
106    if hasattr(ad, "incoming_message_sim_slot_index"):
107        incoming_message_sub_id = get_subid_from_slot_index(
108            log, ad, ad.incoming_message_sim_slot_index)
109    else:
110        incoming_message_sub_id = ad.droid.subscriptionGetDefaultSmsSubId()
111    setattr(ad, "incoming_message_sub_id", incoming_message_sub_id)
112
113
114def get_default_data_sub_id(ad):
115    """ Get default data subscription id
116    """
117    if hasattr(ad, "default_data_sub_id"):
118        return ad.default_data_sub_id
119    else:
120        return ad.droid.subscriptionGetDefaultDataSubId()
121
122
123def get_outgoing_message_sub_id(ad):
124    """ Get outgoing message subscription id
125    """
126    if hasattr(ad, "outgoing_message_sub_id"):
127        return ad.outgoing_message_sub_id
128    else:
129        return ad.droid.subscriptionGetDefaultSmsSubId()
130
131
132def get_outgoing_voice_sub_id(ad):
133    """ Get outgoing voice subscription id
134    """
135    if hasattr(ad, "outgoing_voice_sub_id"):
136        return ad.outgoing_voice_sub_id
137    else:
138        return ad.droid.subscriptionGetDefaultVoiceSubId()
139
140
141def get_incoming_voice_sub_id(ad):
142    """ Get incoming voice subscription id
143    """
144    if hasattr(ad, "incoming_voice_sub_id"):
145        return ad.incoming_voice_sub_id
146    else:
147        return ad.droid.subscriptionGetDefaultVoiceSubId()
148
149
150def get_incoming_message_sub_id(ad):
151    """ Get incoming message subscription id
152    """
153    if hasattr(ad, "incoming_message_sub_id"):
154        return ad.incoming_message_sub_id
155    else:
156        return ad.droid.subscriptionGetDefaultSmsSubId()
157
158
159def get_subid_from_slot_index(log, ad, sim_slot_index):
160    """ Get the subscription ID for a SIM at a particular slot
161
162    Args:
163        ad: android_device object.
164
165    Returns:
166        result: Subscription ID
167    """
168    subInfo = ad.droid.subscriptionGetAllSubInfoList()
169    for info in subInfo:
170        if info['simSlotIndex'] == sim_slot_index:
171            return info['subscriptionId']
172    return INVALID_SUB_ID
173
174
175def get_operatorname_from_slot_index(ad, sim_slot_index):
176    """ Get the operator name for a SIM at a particular slot
177
178    Args:
179        ad: android_device object.
180
181    Returns:
182        result: Operator Name
183    """
184    subInfo = ad.droid.subscriptionGetAllSubInfoList()
185    for info in subInfo:
186        if info['simSlotIndex'] == sim_slot_index:
187            return info['displayName']
188    return None
189
190
191def get_carrierid_from_slot_index(ad, sim_slot_index):
192    """ Get the carrierId for a SIM at a particular slot
193
194    Args:
195        ad: android_device object.
196        sim_slot_index: slot 0 or slot 1
197
198    Returns:
199        result: CarrierId
200    """
201    subInfo = ad.droid.subscriptionGetAllSubInfoList()
202    for info in subInfo:
203        if info['simSlotIndex'] == sim_slot_index:
204            return info['carrierId']
205    return None
206
207
208def set_subid_for_data(ad, sub_id, time_to_sleep=WAIT_TIME_CHANGE_DATA_SUB_ID):
209    """Set subId for data
210
211    Args:
212        ad: android device object.
213        sub_id: subscription id (integer)
214
215    Returns:
216        None
217    """
218    # TODO: Need to check onSubscriptionChanged event. b/27843365
219    if ad.droid.subscriptionGetDefaultDataSubId() != sub_id:
220        ad.droid.subscriptionSetDefaultDataSubId(sub_id)
221        time.sleep(time_to_sleep)
222        setattr(ad, "default_data_sub_id", sub_id)
223
224
225def set_subid_for_message(ad, sub_id):
226    """Set subId for outgoing message
227
228    Args:
229        ad: android device object.
230        sub_id: subscription id (integer)
231
232    Returns:
233        None
234    """
235    ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
236    if hasattr(ad, "outgoing_message_sub_id"):
237        ad.outgoing_message_sub_id = sub_id
238
239
240def set_subid_for_outgoing_call(ad, sub_id):
241    """Set subId for outgoing voice call
242
243    Args:
244        ad: android device object.
245        sub_id: subscription id (integer)
246
247    Returns:
248        None
249    """
250    ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
251    if hasattr(ad, "outgoing_voice_sub_id"):
252        ad.outgoing_voice_sub_id = sub_id
253
254
255def set_incoming_voice_sub_id(ad, sub_id):
256    """Set default subId for voice calls
257
258    Args:
259        ad: android device object.
260        sub_id: subscription id (integer)
261
262    Returns:
263        None
264    """
265    ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
266    if hasattr(ad, "incoming_voice_sub_id"):
267        ad.incoming_voice_sub_id = sub_id
268
269
270def set_default_sub_for_all_services(ad, slot_id=0):
271    """Set subId for all services
272
273    Args:
274        ad: android device object.
275        slot_id: 0 or 1 (integer)
276
277    Returns:
278        None
279    """
280    sub_id = get_subid_from_slot_index(ad.log, ad, slot_id)
281    ad.log.info("Default Subid for all service is %s", sub_id)
282    set_subid_for_outgoing_call(ad, sub_id)
283    set_incoming_voice_sub_id(ad, sub_id)
284    set_subid_for_data(ad, sub_id)
285    set_subid_for_message(ad, sub_id)
286    ad.droid.telephonyToggleDataConnection(True)
287
288
289def perform_dds_switch(ad):
290    slot_dict = {0: {}, 1: {}}
291    for slot in (0,1):
292        slot_dict[slot]['sub_id'] = get_subid_from_slot_index(ad.log, ad, slot)
293        slot_dict[slot]['operator'] = get_operatorname_from_slot_index(ad, slot)
294    ad.log.debug("%s", slot_dict)
295
296    current_data = get_default_data_sub_id(ad)
297    if slot_dict[0]['sub_id'] == current_data:
298        ad.log.info("DDS Switch from %s to %s", slot_dict[0]['operator'],
299                                                slot_dict[1]['operator'])
300        new_data = slot_dict[1]['sub_id']
301        new_oper = slot_dict[1]['operator']
302    else:
303        ad.log.info("DDS Switch from %s to %s", slot_dict[1]['operator'],
304                                                slot_dict[0]['operator'])
305        new_data = slot_dict[0]['sub_id']
306        new_oper = slot_dict[0]['operator']
307    set_subid_for_data(ad, new_data)
308    ad.droid.telephonyToggleDataConnection(True)
309    if get_default_data_sub_id(ad) == new_data:
310        return new_oper
311    else:
312        ad.log.error("DDS Switch Failed")
313        return False
314
315
316def set_dds_on_slot_0(ad):
317    sub_id = get_subid_from_slot_index(ad.log, ad, 0)
318    operator = get_operatorname_from_slot_index(ad, 0)
319    ad.log.info("Setting DDS on %s", operator)
320    set_subid_for_data(ad, sub_id)
321    ad.droid.telephonyToggleDataConnection(True)
322    time.sleep(WAIT_TIME_CHANGE_DATA_SUB_ID)
323    if get_default_data_sub_id(ad) == sub_id:
324        return True
325    else:
326        return False
327
328
329def set_dds_on_slot_1(ad):
330    sub_id = get_subid_from_slot_index(ad.log, ad, 1)
331    operator = get_operatorname_from_slot_index(ad, 1)
332    ad.log.info("Setting DDS on %s", operator)
333    set_subid_for_data(ad, sub_id)
334    ad.droid.telephonyToggleDataConnection(True)
335    time.sleep(WAIT_TIME_CHANGE_DATA_SUB_ID)
336    if get_default_data_sub_id(ad) == sub_id:
337        return True
338    else:
339        return False
340
341
342def set_slways_allow_mms_data(ad, sub_id, state=True):
343    """Set always allow mms data on sub_id
344
345    Args:
346        ad: android device object.
347        sub_id: subscription id (integer)
348        state: True or False
349
350    Returns:
351        None
352    """
353    if "sdm" in ad.model or "msm" in ad.model:
354        ad.log.info("Always allow MMS Data is not supported on platform")
355    else:
356        ad.log.debug("Setting MMS Data Always ON %s sub_id %s", state, sub_id)
357        try:
358            ad.droid.subscriptionSetAlwaysAllowMmsData(sub_id, state)
359        except Exception as e:
360            ad.log.error(e)
361            ad.droid.telephonySetAlwaysAllowMmsData(sub_id, state)
362    return True
363
364
365def get_cbrs_and_default_sub_id(ad):
366    """Gets CBRS and Default SubId
367
368    Args:
369        ad: android device object.
370
371    Returns:
372        cbrs_subId
373        default_subId
374    """
375    slot_dict = {0: {}, 1: {}}
376    for slot in (0, 1):
377        slot_dict[slot]['sub_id'] = get_subid_from_slot_index(
378            ad.log, ad, slot)
379        slot_dict[slot]['carrier_id'] = get_carrierid_from_slot_index(
380            ad, slot)
381        slot_dict[slot]['operator'] = get_operatorname_from_slot_index(
382            ad, slot)
383        if slot_dict[slot]['carrier_id'] == 2340:
384            cbrs_subid = slot_dict[slot]['sub_id']
385        else:
386            default_subid = slot_dict[slot]['sub_id']
387        ad.log.info("Slot %d - Sub %s - Carrier %d - %s", slot,
388                    slot_dict[slot]['sub_id'],
389                    slot_dict[slot]['carrier_id'],
390                    slot_dict[slot]['operator'])
391    return cbrs_subid, default_subid
392