blob: 6fe2444ddaec067bdc475d689e1bf21163430225 [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;
21import android.telephony.PhoneNumberUtils;
22import android.text.TextUtils;
23import android.util.Log;
24
25import com.android.internal.telephony.Connection;
26import com.google.android.collect.Maps;
27
28import java.util.HashMap;
29
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
40 * data into this class. This association is later used in CallModeler when building Call objects
41 * to send to the UI which require the gateway data to show an alert to users.
42 */
43public class CallGatewayManager {
44 private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
45
46 /**
47 * Intent extra to specify the package name of the gateway
48 * provider. Used to get the name displayed in the in-call screen
49 * during the call setup. The value is a string.
50 */
51 // TODO: This extra is currently set by the gateway application as
52 // a temporary measure. Ultimately, the framework will securely
53 // set it.
54 /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
55 "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
56
57 /**
58 * Intent extra to specify the URI of the provider to place the
59 * call. The value is a string. It holds the gateway address
60 * (phone gateway URL should start with the 'tel:' scheme) that
61 * will actually be contacted to call the number passed in the
62 * intent URL or in the EXTRA_PHONE_NUMBER extra.
63 */
64 // TODO: Should the value be a Uri (Parcelable)? Need to make sure
65 // MMI code '#' don't get confused as URI fragments.
66 /* package */ static final String EXTRA_GATEWAY_URI =
67 "com.android.phone.extra.GATEWAY_URI";
68
69 public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
70
71 private final HashMap<Connection, RawGatewayInfo> mMap = Maps.newHashMap();
72
73 public CallGatewayManager() {
74 }
75
76 /**
77 * Static method returns an object containing the gateway data stored in the extras of the
78 * Intent parameter. If no such data exists, returns a Null-Object RawGatewayInfo.
79 * @param intent The intent from which to read gateway data.
80 * @return A populated or empty RawGatewayInfo object.
81 */
82 public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
83 if (hasPhoneProviderExtras(intent)) {
84 return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
85 getProviderGatewayUri(intent), number);
86 }
87 return EMPTY_INFO;
88 }
89
90 /**
91 * This function sets the current mapping from connection to gatewayInfo so that CallModeler
92 * can request this data when creating Call objects.
93 * @param connection The connection object for the placed outgoing call.
94 * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
95 */
96 public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
97 if (!gatewayInfo.isEmpty()) {
98 mMap.put(connection, gatewayInfo);
99 } else {
100 mMap.remove(connection);
101 }
102 }
103
104 /**
105 * Clears the gateway information previously stored via setGatewayInfoForConnection.
106 */
107 public void clearGatewayData(Connection connection) {
108 setGatewayInfoForConnection(connection, EMPTY_INFO);
109 }
110
111 /**
112 * If the parameter matches the connection object we previously saved through
113 * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
114 * return an empty raw gateway info.
115 */
116 public RawGatewayInfo getGatewayInfo(Connection connection) {
117 final RawGatewayInfo info = mMap.get(connection);
118 if (info != null) {
119 return info;
120 }
121
122 return EMPTY_INFO;
123 }
124
125 /**
126 * Check if all the provider's info is present in the intent.
127 * @param intent Expected to have the provider's extra.
128 * @return true if the intent has all the extras to build the
129 * in-call screen's provider info overlay.
130 */
131 public static boolean hasPhoneProviderExtras(Intent intent) {
132 if (null == intent) {
133 return false;
134 }
135 final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
136 final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
137
138 return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
139 }
140
141 /**
142 * Copy all the expected extras set when a 3rd party provider is
143 * used from the source intent to the destination one. Checks all
144 * the required extras are present, if any is missing, none will
145 * be copied.
146 * @param src Intent which may contain the provider's extras.
147 * @param dst Intent where a copy of the extras will be added if applicable.
148 */
149 public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
150 if (!hasPhoneProviderExtras(src)) {
151 Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
152 return;
153 }
154
155 dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
156 src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
157 dst.putExtra(EXTRA_GATEWAY_URI,
158 src.getStringExtra(EXTRA_GATEWAY_URI));
159 }
160
161 /**
162 * Return the gateway uri from the intent.
163 * @param intent With the gateway uri extra.
164 * @return The gateway URI or null if not found.
165 */
166 public static Uri getProviderGatewayUri(Intent intent) {
167 final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
168 return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
169 }
170
171 /**
172 * Return a formatted version of the uri's scheme specific
173 * part. E.g for 'tel:12345678', return '1-234-5678'.
174 * @param uri A 'tel:' URI with the gateway phone number.
175 * @return the provider's address (from the gateway uri) formatted
176 * for user display. null if uri was null or its scheme was not 'tel:'.
177 */
178 public static String formatProviderUri(Uri uri) {
179 if (uri != null) {
180 if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
181 return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
182 } else {
183 return uri.toString();
184 }
185 }
186 return null;
187 }
188
189 public static class RawGatewayInfo {
190 public String packageName;
191 public Uri gatewayUri;
192 public String trueNumber;
193
194 public RawGatewayInfo(String packageName, Uri gatewayUri,
195 String trueNumber) {
196 this.packageName = packageName;
197 this.gatewayUri = gatewayUri;
198 this.trueNumber = trueNumber;
199 }
200
201 public String getFormattedGatewayNumber() {
202 return formatProviderUri(gatewayUri);
203 }
204
205 public boolean isEmpty() {
206 return TextUtils.isEmpty(packageName) || gatewayUri == null;
207 }
208 }
209}