• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telecom.cts.apps;
18 
19 import static android.telecom.CallAttributes.DIRECTION_INCOMING;
20 import static android.telecom.CallAttributes.DIRECTION_OUTGOING;
21 
22 import android.net.Uri;
23 import android.os.Bundle;
24 import android.telecom.CallAttributes;
25 import android.telecom.PhoneAccountHandle;
26 import android.telecom.TelecomManager;
27 
28 import java.util.Random;
29 
30 public class AttributesUtil {
31     private static final Random sRandom = new Random(0);
32     private static final Uri TEST_URI_OUT = Uri.parse("tel:123-TEST");
33     private static final String TEST_NAME_OUT = "Mike Tyson";
34     private static final Uri TEST_URI_IN = Uri.parse("tel:456-TEST");
35     private static final String TEST_NAME_IN = "Alan Turing";
36     public static final String TEST_EMERGENCY_NUMBER = "5553637";
37     private static final Uri TEST_EMERGENCY_URI = Uri.fromParts("tel", TEST_EMERGENCY_NUMBER, null);
38     public static final String SYSTEM_DIALER_PKG_NAME = "android.telecom.cts.cuj/.CujInCallService";
39     public static final String TEST_EMERGENCY_MANAGED_PHONE_ACCOUNT_PKG_NAME =
40             "android.telecom.cts.apps.managedapp";
41     public static final String TEST_EMERGENCY_MANAGED_CLONE_PHONE_ACCOUNT_PKG_NAME =
42             "android.telecom.cts.apps.managedappclone";
43     private static final Uri TEST_IN_CALL_MMI_URI = Uri.parse("tel:0");
44     private static final Uri TEST_MMI_URI = Uri.parse("tel:*%2306%23");
45 
46     /**
47      * @return true if the call is holdable according to the CallAttributes
48      */
hasSetInactiveCapabilities(CallAttributes callAttributes)49     public static boolean hasSetInactiveCapabilities(CallAttributes callAttributes) {
50         return (callAttributes.getCallCapabilities() & CallAttributes.SUPPORTS_SET_INACTIVE)
51                 == CallAttributes.SUPPORTS_SET_INACTIVE;
52     }
53 
54     /**
55      * @return a CallAttributes object for the given TelecomAppName. The Name and Address are
56      * defaulted depending on the direction.
57      */
getDefaultAttributesForApp(TelecomTestApp name, boolean isOutgoing)58     public static CallAttributes getDefaultAttributesForApp(TelecomTestApp name, boolean isOutgoing)
59             throws Exception {
60         return new CallAttributes.Builder(
61                 getPhoneAccountHandleForApp(name),
62                 getDirectionFromBool(isOutgoing),
63                 getDefaultName(isOutgoing), getDefaultAddress(isOutgoing))
64                 .setCallType(CallAttributes.AUDIO_CALL)
65                 .setCallCapabilities(CallAttributes.SUPPORTS_SET_INACTIVE)
66                 .build();
67     }
68 
69     /**
70      * @return a CallAttributes object for the given TelecomAppName. The Name and Address are
71      * randomized!
72      */
getRandomAttributesForApp(TelecomTestApp name, boolean isOutgoing, boolean isHoldable)73     public static CallAttributes getRandomAttributesForApp(TelecomTestApp name,
74             boolean isOutgoing,
75             boolean isHoldable)
76             throws Exception {
77         return new CallAttributes.Builder(
78                 getPhoneAccountHandleForApp(name),
79                 getDirectionFromBool(isOutgoing),
80                 getRandomName(), getRandomAddress())
81                 .setCallType(CallAttributes.AUDIO_CALL)
82                 .setCallCapabilities(setCallCapabilities(isHoldable))
83                 .build();
84     }
85 
86     /**
87      * @return a CallAttributes object for the MANAGED_APP. The Name and Address are defaulted
88      *     depending on the direction.
89      */
getDefaultAttributesForManaged( PhoneAccountHandle handle, boolean isOutgoing, boolean isEmergency)90     public static CallAttributes getDefaultAttributesForManaged(
91             PhoneAccountHandle handle, boolean isOutgoing, boolean isEmergency) {
92         return new CallAttributes.Builder(
93                         handle,
94                         getDirectionFromBool(isOutgoing),
95                         TEST_NAME_IN,
96                         isEmergency
97                                 ? getDefaultAddressForEmergency()
98                                 : getDefaultAddress(isOutgoing))
99                 .setCallType(CallAttributes.AUDIO_CALL)
100                 .setCallCapabilities(CallAttributes.SUPPORTS_SET_INACTIVE)
101                 .build();
102     }
103 
104     /**
105      * @return a CallAttributes object for verifying MMI codes.
106      */
getDefaultMmiAttributesForApp( TelecomTestApp name, PhoneAccountHandle handle, boolean inCallMmi)107     public static CallAttributes getDefaultMmiAttributesForApp(
108             TelecomTestApp name, PhoneAccountHandle handle, boolean inCallMmi) throws Exception {
109         if (handle == null) {
110             handle = getPhoneAccountHandleForApp(name);
111         }
112         return new CallAttributes.Builder(
113                         handle, DIRECTION_OUTGOING, TEST_NAME_OUT, getDefaultMmiAddress(inCallMmi))
114                 .setCallType(CallAttributes.AUDIO_CALL)
115                 .setCallCapabilities(CallAttributes.SUPPORTS_SET_INACTIVE)
116                 .build();
117     }
118 
119     /**
120      * @return a CallAttributes object for the MANAGED_APP. The Name and Address are
121      * randomized!
122      */
getRandomAttributesForManaged(PhoneAccountHandle handle, boolean isOutgoing, boolean isHoldable)123     public static CallAttributes getRandomAttributesForManaged(PhoneAccountHandle handle,
124             boolean isOutgoing,
125             boolean isHoldable) {
126         return new CallAttributes.Builder(
127                 handle,
128                 getDirectionFromBool(isOutgoing),
129                 getRandomName(), getRandomAddress())
130                 .setCallType(CallAttributes.AUDIO_CALL)
131                 .setCallCapabilities(setCallCapabilities(isHoldable))
132                 .build();
133     }
134 
135     /**
136      * This method should help set the CallCapabilities that are defined in the CallAttributes
137      * class
138      */
setCallCapabilities(boolean isHoldable)139     public static int setCallCapabilities(boolean isHoldable) {
140         return isHoldable ? CallAttributes.SUPPORTS_SET_INACTIVE : 0;
141     }
142 
143     /**
144      * @return The [PhoneAccountHandle] for the given TelecomAppName that is defined in the
145      * application.info package
146      */
getPhoneAccountHandleForApp(TelecomTestApp name)147     public static PhoneAccountHandle getPhoneAccountHandleForApp(TelecomTestApp name)
148             throws Exception {
149         switch (name) {
150             case TransactionalVoipAppMain -> {
151                 return TelecomTestApp.TRANSACTIONAL_APP_DEFAULT_HANDLE;
152             }
153             case TransactionalVoipAppClone -> {
154                 return TelecomTestApp.TRANSACTIONAL_APP_CLONE_DEFAULT_HANDLE;
155             }
156             case ConnectionServiceVoipAppMain -> {
157                 return TelecomTestApp.SELF_MANAGED_CS_MAIN_HANDLE;
158             }
159             case ConnectionServiceVoipAppClone -> {
160                 return TelecomTestApp.SELF_MANAGED_CS_CLONE_HANDLE;
161             }
162             case ManagedConnectionServiceApp -> {
163                 throw new Exception("The PhoneAccount for ManagedConnectionServiceApp is not"
164                         + " is kept in BaseAppVerifier");
165             }
166             case ManagedConnectionServiceAppClone -> {
167                 throw new Exception("The PhoneAccount for ManagedConnectionServiceAppClone is not"
168                         + " is kept in BaseAppVerifier");
169             }
170         }
171         throw new Exception(String.format("%s does not have a PhoneAccount mapping", name));
172     }
173 
174     /**
175      * @return injects the [PhoneAccountHandle] that is defined in the [CallAttribute]s object into
176      * a Bundle.
177      */
getExtrasWithPhoneAccount(CallAttributes callAttributes)178     public static Bundle getExtrasWithPhoneAccount(CallAttributes callAttributes) {
179         Bundle extras = new Bundle();
180         extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
181                 callAttributes.getPhoneAccountHandle());
182         if (!isOutgoing(callAttributes)) {
183             extras.putParcelable(
184                     TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
185                     callAttributes.getAddress()
186             );
187         }
188         return extras;
189     }
190 
191     /**
192      * @return true if the call is outgoing bases on the [CallAttribute]s object
193      */
isOutgoing(CallAttributes callAttributes)194     public static boolean isOutgoing(CallAttributes callAttributes) {
195         return callAttributes.getDirection() == DIRECTION_OUTGOING;
196     }
197 
getDirectionFromBool(boolean isOutgoing)198     private static int getDirectionFromBool(boolean isOutgoing) {
199         return isOutgoing ? DIRECTION_OUTGOING : DIRECTION_INCOMING;
200     }
201 
getDefaultAddress(boolean isOutgoing)202     private static Uri getDefaultAddress(boolean isOutgoing) {
203         return isOutgoing ? TEST_URI_OUT : TEST_URI_IN;
204     }
205 
getDefaultAddressForEmergency()206     private static Uri getDefaultAddressForEmergency() {
207         return TEST_EMERGENCY_URI;
208     }
209 
getDefaultMmiAddress(boolean inCallMmi)210     private static Uri getDefaultMmiAddress(boolean inCallMmi) {
211         return inCallMmi ? TEST_IN_CALL_MMI_URI : TEST_MMI_URI;
212     }
213 
getDefaultName(boolean isOutgoing)214     private static String getDefaultName(boolean isOutgoing) {
215         return isOutgoing ? TEST_NAME_IN : TEST_NAME_OUT;
216     }
217 
getRandomName()218     private static String getRandomName() {
219         StringBuilder builder = new StringBuilder();
220         for (int i = 0; i < 16; i++) {
221             builder.append((char) sRandom.nextInt('a', 'z'));
222         }
223         return builder.toString();
224     }
225 
getRandomAddress()226     private static Uri getRandomAddress() {
227         StringBuilder builder = new StringBuilder("tel:");
228         for (int i = 0; i < 11; i++) {
229             builder.append(sRandom.nextInt(10));
230         }
231         return Uri.parse(builder.toString());
232     }
233 }
234