169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon/* 269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Copyright (C) 2013 The Android Open Source Project 369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * you may not use this file except in compliance with the License. 669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * You may obtain a copy of the License at 769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * http://www.apache.org/licenses/LICENSE-2.0 969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 1069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Unless required by applicable law or agreed to in writing, software 1169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 1269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * See the License for the specific language governing permissions and 1469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * limitations under the License. 1569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 1669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 1769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonpackage com.android.phone; 1869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 1969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport android.content.Intent; 2069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport android.net.Uri; 214d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccount; 2269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport android.telephony.PhoneNumberUtils; 2369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport android.text.TextUtils; 2469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport android.util.Log; 2569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 2669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonimport com.android.internal.telephony.Connection; 2769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 2821a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shraunerimport java.util.concurrent.ConcurrentHashMap; 2969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 3069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon/** 3169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * This class manages gateway information for outgoing calls. When calls are made, they may contain 3269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * gateway information for services which route phone calls through their own service/numbers. 3369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * The data consists of a number to call and the package name of the service. This data is used in 3469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * two ways:<br/> 3569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 1. Call the appropriate routing number<br/> 3669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 2. Display information about the routing to the user<br/> 3769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * 3869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the 3969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * proper number to dial. It also saves an association between the connection object and the gateway 4023d9ed758fbe78e4afd4067e6845bcaf3387bca7Sailesh Nepal * data into this class. 4169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 4269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordonpublic class CallGatewayManager { 4369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon private static final String LOG_TAG = CallGatewayManager.class.getSimpleName(); 4469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 4569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 4669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Intent extra to specify the package name of the gateway 4769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * provider. Used to get the name displayed in the in-call screen 4869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * during the call setup. The value is a string. 4969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 5069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon // TODO: This extra is currently set by the gateway application as 5169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon // a temporary measure. Ultimately, the framework will securely 5269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon // set it. 5369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE = 5469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE"; 5569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 5669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 5769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Intent extra to specify the URI of the provider to place the 5869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * call. The value is a string. It holds the gateway address 5969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * (phone gateway URL should start with the 'tel:' scheme) that 6069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * will actually be contacted to call the number passed in the 6169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * intent URL or in the EXTRA_PHONE_NUMBER extra. 6269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 6369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon // TODO: Should the value be a Uri (Parcelable)? Need to make sure 6469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon // MMI code '#' don't get confused as URI fragments. 6569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /* package */ static final String EXTRA_GATEWAY_URI = 6669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon "com.android.phone.extra.GATEWAY_URI"; 6769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 6869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null); 6969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 7021a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner private final ConcurrentHashMap<Connection, RawGatewayInfo> mMap = 7121a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner new ConcurrentHashMap<Connection, RawGatewayInfo>(4, 0.9f, 1); 7269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 7321a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner private static CallGatewayManager sSingleton; 7421a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner 7521a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner public static synchronized CallGatewayManager getInstance() { 7621a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner if (sSingleton == null) { 7721a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner sSingleton = new CallGatewayManager(); 7821a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner } 7921a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner return sSingleton; 8021a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner } 8121a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner 8221a7534fa69c1cc10809ae33fa0bfa84c5ac1309Jay Shrauner private CallGatewayManager() { 8369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 8469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 8569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 8669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Static method returns an object containing the gateway data stored in the extras of the 8769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Intent parameter. If no such data exists, returns a Null-Object RawGatewayInfo. 8869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param intent The intent from which to read gateway data. 8969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @return A populated or empty RawGatewayInfo object. 9069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 9169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) { 9269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (hasPhoneProviderExtras(intent)) { 9369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE), 9469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon getProviderGatewayUri(intent), number); 9569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 9669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return EMPTY_INFO; 9769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 9869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 9969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 10023d9ed758fbe78e4afd4067e6845bcaf3387bca7Sailesh Nepal * This function sets the current mapping from connection to gatewayInfo. 10169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param connection The connection object for the placed outgoing call. 10269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param gatewayInfo Gateway info gathered using getRawGatewayInfo. 10369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 10469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) { 10569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (!gatewayInfo.isEmpty()) { 10669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon mMap.put(connection, gatewayInfo); 10769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } else { 10869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon mMap.remove(connection); 10969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 11069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 11169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 11269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 11369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Clears the gateway information previously stored via setGatewayInfoForConnection. 11469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 11569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public void clearGatewayData(Connection connection) { 11669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon setGatewayInfoForConnection(connection, EMPTY_INFO); 11769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 11869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 11969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 12069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * If the parameter matches the connection object we previously saved through 12169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then 12269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * return an empty raw gateway info. 12369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 12469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public RawGatewayInfo getGatewayInfo(Connection connection) { 12569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon final RawGatewayInfo info = mMap.get(connection); 12669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (info != null) { 12769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return info; 12869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 12969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 13069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return EMPTY_INFO; 13169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 13269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 13369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 13469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Check if all the provider's info is present in the intent. 13569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param intent Expected to have the provider's extra. 13669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @return true if the intent has all the extras to build the 13769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * in-call screen's provider info overlay. 13869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 13969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static boolean hasPhoneProviderExtras(Intent intent) { 14069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (null == intent) { 14169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return false; 14269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 14369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE); 14469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI); 14569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 14669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri); 14769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 14869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 14969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 15069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Copy all the expected extras set when a 3rd party provider is 15169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * used from the source intent to the destination one. Checks all 15269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * the required extras are present, if any is missing, none will 15369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * be copied. 15469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param src Intent which may contain the provider's extras. 15569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param dst Intent where a copy of the extras will be added if applicable. 15669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 15769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) { 15869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (!hasPhoneProviderExtras(src)) { 15969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing."); 16069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return; 16169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 16269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 16369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE, 16469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE)); 16569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon dst.putExtra(EXTRA_GATEWAY_URI, 16669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon src.getStringExtra(EXTRA_GATEWAY_URI)); 16769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 16869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 16969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 17069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Return the gateway uri from the intent. 17169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param intent With the gateway uri extra. 17269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @return The gateway URI or null if not found. 17369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 17469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static Uri getProviderGatewayUri(Intent intent) { 17569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI); 17669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return TextUtils.isEmpty(uri) ? null : Uri.parse(uri); 17769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 17869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 17969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon /** 18069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * Return a formatted version of the uri's scheme specific 18169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * part. E.g for 'tel:12345678', return '1-234-5678'. 18269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @param uri A 'tel:' URI with the gateway phone number. 18369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * @return the provider's address (from the gateway uri) formatted 18469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon * for user display. null if uri was null or its scheme was not 'tel:'. 18569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon */ 18669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static String formatProviderUri(Uri uri) { 18769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon if (uri != null) { 188137458b4bf3516941483e59c123c22cbee27ed43Jay Shrauner if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) { 18969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart()); 19069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } else { 19169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return uri.toString(); 19269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 19369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 19469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return null; 19569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 19669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 19769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public static class RawGatewayInfo { 19869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public String packageName; 19969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public Uri gatewayUri; 20069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public String trueNumber; 20169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 20269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public RawGatewayInfo(String packageName, Uri gatewayUri, 20369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon String trueNumber) { 20469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon this.packageName = packageName; 20569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon this.gatewayUri = gatewayUri; 20669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon this.trueNumber = trueNumber; 20769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 20869a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 20969a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public String getFormattedGatewayNumber() { 21069a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return formatProviderUri(gatewayUri); 21169a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 21269a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon 21369a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon public boolean isEmpty() { 21469a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon return TextUtils.isEmpty(packageName) || gatewayUri == null; 21569a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 21669a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon } 21769a691914e9b013a7ff52c129d8466c152ed7239Santos Cordon} 218