13921359f3f01938768f0b0e731941542f0385787Yorke Lee/* 23921359f3f01938768f0b0e731941542f0385787Yorke Lee * Copyright (C) 2014 The Android Open Source Project 33921359f3f01938768f0b0e731941542f0385787Yorke Lee * 43921359f3f01938768f0b0e731941542f0385787Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); 53921359f3f01938768f0b0e731941542f0385787Yorke Lee * you may not use this file except in compliance with the License. 63921359f3f01938768f0b0e731941542f0385787Yorke Lee * You may obtain a copy of the License at 73921359f3f01938768f0b0e731941542f0385787Yorke Lee * 83921359f3f01938768f0b0e731941542f0385787Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0 93921359f3f01938768f0b0e731941542f0385787Yorke Lee * 103921359f3f01938768f0b0e731941542f0385787Yorke Lee * Unless required by applicable law or agreed to in writing, software 113921359f3f01938768f0b0e731941542f0385787Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS, 123921359f3f01938768f0b0e731941542f0385787Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133921359f3f01938768f0b0e731941542f0385787Yorke Lee * See the License for the specific language governing permissions and 143921359f3f01938768f0b0e731941542f0385787Yorke Lee * limitations under the License. 153921359f3f01938768f0b0e731941542f0385787Yorke Lee */ 163921359f3f01938768f0b0e731941542f0385787Yorke Leepackage com.android.dialer.util; 173921359f3f01938768f0b0e731941542f0385787Yorke Lee 1872d59616b7a491d41c9b127b777c63fe315ecd06Yorke Leeimport android.app.Activity; 193921359f3f01938768f0b0e731941542f0385787Yorke Leeimport android.content.ActivityNotFoundException; 2046fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport android.content.ComponentName; 213921359f3f01938768f0b0e731941542f0385787Yorke Leeimport android.content.Context; 223921359f3f01938768f0b0e731941542f0385787Yorke Leeimport android.content.Intent; 2346fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport android.content.pm.PackageManager; 2446fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport android.content.pm.ResolveInfo; 250a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Leeimport android.content.res.Resources; 260d3a73932a23cb07168d25ec331a9abf72817346Nancy Chenimport android.graphics.Point; 2746fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport android.net.Uri; 280d3a73932a23cb07168d25ec331a9abf72817346Nancy Chenimport android.os.Bundle; 2946fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport android.provider.Telephony; 309dc924c8bcc0bc8d996452e9ce3215b5f064962eTyler Gunnimport android.telecom.TelecomManager; 31f4cb047c49e061cd0590a53d0a176233019eb906Andrew Leeimport android.text.BidiFormatter; 32f4cb047c49e061cd0590a53d0a176233019eb906Andrew Leeimport android.text.TextDirectionHeuristics; 338b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunnimport android.text.TextUtils; 340a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Leeimport android.view.View; 35f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Leeimport android.view.inputmethod.InputMethodManager; 360a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Leeimport android.widget.ImageView; 370a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Leeimport android.widget.TextView; 383921359f3f01938768f0b0e731941542f0385787Yorke Leeimport android.widget.Toast; 393921359f3f01938768f0b0e731941542f0385787Yorke Lee 40ae274c05cdb6707ca9593bedf20c016cd8164c0bJay Shraunerimport com.android.contacts.common.ContactsUtils; 410d3a73932a23cb07168d25ec331a9abf72817346Nancy Chenimport com.android.contacts.common.interactions.TouchPointManager; 423921359f3f01938768f0b0e731941542f0385787Yorke Leeimport com.android.dialer.R; 4338019af70eb1ca084d36291390bbc54dc81027deYorke Leeimport com.android.dialer.widget.EmptyContentView; 440d3a73932a23cb07168d25ec331a9abf72817346Nancy Chenimport com.android.incallui.CallCardFragment; 450d3a73932a23cb07168d25ec331a9abf72817346Nancy Chenimport com.android.incallui.Log; 463921359f3f01938768f0b0e731941542f0385787Yorke Lee 47f4cb047c49e061cd0590a53d0a176233019eb906Andrew Leeimport java.util.ArrayList; 48f4cb047c49e061cd0590a53d0a176233019eb906Andrew Leeimport java.util.Iterator; 4946fd712ad2896858d977274f94a08aef5bdf0e4cYorke Leeimport java.util.List; 5069c247f619fd2f2474070bdbcec32b78f6444149Yorke Leeimport java.util.Locale; 5146fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee 523921359f3f01938768f0b0e731941542f0385787Yorke Lee/** 533921359f3f01938768f0b0e731941542f0385787Yorke Lee * General purpose utility methods for the Dialer. 543921359f3f01938768f0b0e731941542f0385787Yorke Lee */ 553921359f3f01938768f0b0e731941542f0385787Yorke Leepublic class DialerUtils { 563921359f3f01938768f0b0e731941542f0385787Yorke Lee 573921359f3f01938768f0b0e731941542f0385787Yorke Lee /** 583921359f3f01938768f0b0e731941542f0385787Yorke Lee * Attempts to start an activity and displays a toast with the default error message if the 593921359f3f01938768f0b0e731941542f0385787Yorke Lee * activity is not found, instead of throwing an exception. 603921359f3f01938768f0b0e731941542f0385787Yorke Lee * 613921359f3f01938768f0b0e731941542f0385787Yorke Lee * @param context to start the activity with. 623921359f3f01938768f0b0e731941542f0385787Yorke Lee * @param intent to start the activity with. 633921359f3f01938768f0b0e731941542f0385787Yorke Lee */ 643921359f3f01938768f0b0e731941542f0385787Yorke Lee public static void startActivityWithErrorToast(Context context, Intent intent) { 653921359f3f01938768f0b0e731941542f0385787Yorke Lee startActivityWithErrorToast(context, intent, R.string.activity_not_available); 663921359f3f01938768f0b0e731941542f0385787Yorke Lee } 673921359f3f01938768f0b0e731941542f0385787Yorke Lee 683921359f3f01938768f0b0e731941542f0385787Yorke Lee /** 693921359f3f01938768f0b0e731941542f0385787Yorke Lee * Attempts to start an activity and displays a toast with a provided error message if the 703921359f3f01938768f0b0e731941542f0385787Yorke Lee * activity is not found, instead of throwing an exception. 713921359f3f01938768f0b0e731941542f0385787Yorke Lee * 723921359f3f01938768f0b0e731941542f0385787Yorke Lee * @param context to start the activity with. 733921359f3f01938768f0b0e731941542f0385787Yorke Lee * @param intent to start the activity with. 743921359f3f01938768f0b0e731941542f0385787Yorke Lee * @param msgId Resource ID of the string to display in an error message if the activity is 753921359f3f01938768f0b0e731941542f0385787Yorke Lee * not found. 763921359f3f01938768f0b0e731941542f0385787Yorke Lee */ 773921359f3f01938768f0b0e731941542f0385787Yorke Lee public static void startActivityWithErrorToast(Context context, Intent intent, int msgId) { 783921359f3f01938768f0b0e731941542f0385787Yorke Lee try { 79247df6ee4f43af916f7e7f339ed181a18807ef36Andrew Lee if ((IntentUtil.CALL_ACTION.equals(intent.getAction()) 80b82e8dae149a9f247e5c9fcae02ced460670b0e7Yorke Lee && context instanceof Activity)) { 810d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen // All dialer-initiated calls should pass the touch point to the InCallUI 820d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen Point touchPoint = TouchPointManager.getInstance().getPoint(); 830d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen if (touchPoint.x != 0 || touchPoint.y != 0) { 840d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen Bundle extras = new Bundle(); 850d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen extras.putParcelable(TouchPointManager.TOUCH_POINT, touchPoint); 869dc924c8bcc0bc8d996452e9ce3215b5f064962eTyler Gunn intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); 870d3a73932a23cb07168d25ec331a9abf72817346Nancy Chen } 88b82e8dae149a9f247e5c9fcae02ced460670b0e7Yorke Lee final TelecomManager tm = 89b82e8dae149a9f247e5c9fcae02ced460670b0e7Yorke Lee (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); 90b82e8dae149a9f247e5c9fcae02ced460670b0e7Yorke Lee tm.placeCall(intent.getData(), intent.getExtras()); 9172d59616b7a491d41c9b127b777c63fe315ecd06Yorke Lee } else { 9272d59616b7a491d41c9b127b777c63fe315ecd06Yorke Lee context.startActivity(intent); 9372d59616b7a491d41c9b127b777c63fe315ecd06Yorke Lee } 943921359f3f01938768f0b0e731941542f0385787Yorke Lee } catch (ActivityNotFoundException e) { 953921359f3f01938768f0b0e731941542f0385787Yorke Lee Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show(); 963921359f3f01938768f0b0e731941542f0385787Yorke Lee } 973921359f3f01938768f0b0e731941542f0385787Yorke Lee } 9846fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee 9946fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee /** 10046fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee * Returns the component name to use in order to send an SMS using the default SMS application, 10146fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee * or null if none exists. 10246fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee */ 10346fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee public static ComponentName getSmsComponent(Context context) { 10446fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee String smsPackage = Telephony.Sms.getDefaultSmsPackage(context); 10546fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee if (smsPackage != null) { 10646fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee final PackageManager packageManager = context.getPackageManager(); 10746fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee final Intent intent = new Intent(Intent.ACTION_SENDTO, 108ae274c05cdb6707ca9593bedf20c016cd8164c0bJay Shrauner Uri.fromParts(ContactsUtils.SCHEME_SMSTO, "", null)); 10946fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0); 11046fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee for (ResolveInfo resolveInfo : resolveInfos) { 11146fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee if (smsPackage.equals(resolveInfo.activityInfo.packageName)) { 11246fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee return new ComponentName(smsPackage, resolveInfo.activityInfo.name); 11346fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee } 11446fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee } 11546fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee } 11646fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee return null; 11746fd712ad2896858d977274f94a08aef5bdf0e4cYorke Lee } 1180a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Lee 1190a4327e6bfeedc23ddefb4df9f6e8041ebc87b59Andrew Lee /** 12035ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee * Closes an {@link AutoCloseable}, silently ignoring any checked exceptions. Does nothing if 12135ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee * null. 12235ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee * 12335ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee * @param closeable to close. 12435ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee */ 12535ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee public static void closeQuietly(AutoCloseable closeable) { 12635ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee if (closeable != null) { 12735ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee try { 12835ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee closeable.close(); 12935ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee } catch (RuntimeException rethrown) { 13035ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee throw rethrown; 13135ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee } catch (Exception ignored) { 13235ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee } 13335ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee } 13435ee63feb37dcc38483a35e11fff3f16bb0bfe75Yorke Lee } 1358b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn 1368b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn /** 1378b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * Joins a list of {@link CharSequence} into a single {@link CharSequence} seperated by a 1388b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * localized delimiter such as ", ". 1398b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * 1408b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @param resources Resources used to get list delimiter. 1418b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @param list List of char sequences to join. 1428b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @return Joined char sequences. 1438b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn */ 1448b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn public static CharSequence join(Resources resources, Iterable<CharSequence> list) { 145f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee StringBuilder sb = new StringBuilder(); 146f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee final BidiFormatter formatter = BidiFormatter.getInstance(); 1478b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn final CharSequence separator = resources.getString(R.string.list_delimeter); 148f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee 149f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee Iterator<CharSequence> itr = list.iterator(); 150f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee boolean firstTime = true; 151f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee while (itr.hasNext()) { 152f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee if (firstTime) { 153f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee firstTime = false; 154f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee } else { 155f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee sb.append(separator); 156f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee } 157f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee // Unicode wrap the elements of the list to respect RTL for individual strings. 158f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee sb.append(formatter.unicodeWrap( 159f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee itr.next().toString(), TextDirectionHeuristics.FIRSTSTRONG_LTR)); 160f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee } 161f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee 162f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee // Unicode wrap the joined value, to respect locale's RTL ordering for the whole list. 163f4cb047c49e061cd0590a53d0a176233019eb906Andrew Lee return formatter.unicodeWrap(sb.toString()); 1648b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn } 16569c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee 16669c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee /** 16769c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee * @return True if the application is currently in RTL mode. 16869c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee */ 16969c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee public static boolean isRtl() { 17069c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == 17169c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee View.LAYOUT_DIRECTION_RTL; 17269c247f619fd2f2474070bdbcec32b78f6444149Yorke Lee } 173f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee 174f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee public static void showInputMethod(View view) { 175f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( 176f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee Context.INPUT_METHOD_SERVICE); 177f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee if (imm != null) { 178f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee imm.showSoftInput(view, 0); 179f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee } 180f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee } 181f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee 182f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee public static void hideInputMethod(View view) { 183f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( 184f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee Context.INPUT_METHOD_SERVICE); 185f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee if (imm != null) { 186f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 187f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee } 188f543baadd1119bad7cd9ff7ed39e5598c6fc50d6Yorke Lee } 1893921359f3f01938768f0b0e731941542f0385787Yorke Lee} 190