blob: bdac98354ebb89e6d5025d9e50b5a688ac4af837 [file] [log] [blame]
Santos Cordon69a69192013-08-22 14:25:42 -07001/*
2 * Copyright (C) 2013 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
17package com.android.phone;
18
19import android.content.Intent;
20import android.net.Uri;
Tyler Gunn4d45d1c2014-09-12 22:17:53 -070021import android.telecom.PhoneAccount;
Santos Cordon69a69192013-08-22 14:25:42 -070022import android.telephony.PhoneNumberUtils;
23import android.text.TextUtils;
24import android.util.Log;
25
26import com.android.internal.telephony.Connection;
Santos Cordon69a69192013-08-22 14:25:42 -070027
Jay Shrauner21a75342013-11-25 16:14:43 -080028import java.util.concurrent.ConcurrentHashMap;
Santos Cordon69a69192013-08-22 14:25:42 -070029
30/**
31 * This class manages gateway information for outgoing calls. When calls are made, they may contain
32 * gateway information for services which route phone calls through their own service/numbers.
33 * The data consists of a number to call and the package name of the service. This data is used in
34 * two ways:<br/>
35 * 1. Call the appropriate routing number<br/>
36 * 2. Display information about the routing to the user<br/>
37 *
38 * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the
39 * proper number to dial. It also saves an association between the connection object and the gateway
Sailesh Nepal23d9ed72014-07-03 09:40:26 -070040 * data into this class.
Santos Cordon69a69192013-08-22 14:25:42 -070041 */
42public class CallGatewayManager {
43 private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
44
45 /**
46 * Intent extra to specify the package name of the gateway
47 * provider. Used to get the name displayed in the in-call screen
48 * during the call setup. The value is a string.
49 */
50 // TODO: This extra is currently set by the gateway application as
51 // a temporary measure. Ultimately, the framework will securely
52 // set it.
53 /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
54 "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
55
56 /**
57 * Intent extra to specify the URI of the provider to place the
58 * call. The value is a string. It holds the gateway address
59 * (phone gateway URL should start with the 'tel:' scheme) that
60 * will actually be contacted to call the number passed in the
61 * intent URL or in the EXTRA_PHONE_NUMBER extra.
62 */
63 // TODO: Should the value be a Uri (Parcelable)? Need to make sure
64 // MMI code '#' don't get confused as URI fragments.
65 /* package */ static final String EXTRA_GATEWAY_URI =
66 "com.android.phone.extra.GATEWAY_URI";
67
68 public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
69
Jay Shrauner21a75342013-11-25 16:14:43 -080070 private final ConcurrentHashMap<Connection, RawGatewayInfo> mMap =
71 new ConcurrentHashMap<Connection, RawGatewayInfo>(4, 0.9f, 1);
Santos Cordon69a69192013-08-22 14:25:42 -070072
Jay Shrauner21a75342013-11-25 16:14:43 -080073 private static CallGatewayManager sSingleton;
74
75 public static synchronized CallGatewayManager getInstance() {
76 if (sSingleton == null) {
77 sSingleton = new CallGatewayManager();
78 }
79 return sSingleton;
80 }
81
82 private CallGatewayManager() {
Santos Cordon69a69192013-08-22 14:25:42 -070083 }
84
85 /**
86 * Static method returns an object containing the gateway data stored in the extras of the
87 * Intent parameter. If no such data exists, returns a Null-Object RawGatewayInfo.
88 * @param intent The intent from which to read gateway data.
89 * @return A populated or empty RawGatewayInfo object.
90 */
91 public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
92 if (hasPhoneProviderExtras(intent)) {
93 return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
94 getProviderGatewayUri(intent), number);
95 }
96 return EMPTY_INFO;
97 }
98
99 /**
Sailesh Nepal23d9ed72014-07-03 09:40:26 -0700100 * This function sets the current mapping from connection to gatewayInfo.
Santos Cordon69a69192013-08-22 14:25:42 -0700101 * @param connection The connection object for the placed outgoing call.
102 * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
103 */
104 public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
105 if (!gatewayInfo.isEmpty()) {
106 mMap.put(connection, gatewayInfo);
107 } else {
108 mMap.remove(connection);
109 }
110 }
111
112 /**
113 * Clears the gateway information previously stored via setGatewayInfoForConnection.
114 */
115 public void clearGatewayData(Connection connection) {
116 setGatewayInfoForConnection(connection, EMPTY_INFO);
117 }
118
119 /**
120 * If the parameter matches the connection object we previously saved through
121 * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
122 * return an empty raw gateway info.
123 */
124 public RawGatewayInfo getGatewayInfo(Connection connection) {
125 final RawGatewayInfo info = mMap.get(connection);
126 if (info != null) {
127 return info;
128 }
129
130 return EMPTY_INFO;
131 }
132
133 /**
134 * Check if all the provider's info is present in the intent.
135 * @param intent Expected to have the provider's extra.
136 * @return true if the intent has all the extras to build the
137 * in-call screen's provider info overlay.
138 */
139 public static boolean hasPhoneProviderExtras(Intent intent) {
140 if (null == intent) {
141 return false;
142 }
143 final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
144 final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
145
146 return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
147 }
148
149 /**
150 * Copy all the expected extras set when a 3rd party provider is
151 * used from the source intent to the destination one. Checks all
152 * the required extras are present, if any is missing, none will
153 * be copied.
154 * @param src Intent which may contain the provider's extras.
155 * @param dst Intent where a copy of the extras will be added if applicable.
156 */
157 public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
158 if (!hasPhoneProviderExtras(src)) {
159 Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
160 return;
161 }
162
163 dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
164 src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
165 dst.putExtra(EXTRA_GATEWAY_URI,
166 src.getStringExtra(EXTRA_GATEWAY_URI));
167 }
168
169 /**
170 * Return the gateway uri from the intent.
171 * @param intent With the gateway uri extra.
172 * @return The gateway URI or null if not found.
173 */
174 public static Uri getProviderGatewayUri(Intent intent) {
175 final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
176 return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
177 }
178
179 /**
180 * Return a formatted version of the uri's scheme specific
181 * part. E.g for 'tel:12345678', return '1-234-5678'.
182 * @param uri A 'tel:' URI with the gateway phone number.
183 * @return the provider's address (from the gateway uri) formatted
184 * for user display. null if uri was null or its scheme was not 'tel:'.
185 */
186 public static String formatProviderUri(Uri uri) {
187 if (uri != null) {
Jay Shrauner137458b2014-09-05 14:27:25 -0700188 if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
Santos Cordon69a69192013-08-22 14:25:42 -0700189 return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
190 } else {
191 return uri.toString();
192 }
193 }
194 return null;
195 }
196
197 public static class RawGatewayInfo {
198 public String packageName;
199 public Uri gatewayUri;
200 public String trueNumber;
201
202 public RawGatewayInfo(String packageName, Uri gatewayUri,
203 String trueNumber) {
204 this.packageName = packageName;
205 this.gatewayUri = gatewayUri;
206 this.trueNumber = trueNumber;
207 }
208
209 public String getFormattedGatewayNumber() {
210 return formatProviderUri(gatewayUri);
211 }
212
213 public boolean isEmpty() {
214 return TextUtils.isEmpty(packageName) || gatewayUri == null;
215 }
216 }
217}