• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 package com.android.dialer.util;
17 
18 import android.app.Activity;
19 import android.content.ActivityNotFoundException;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.res.Resources;
26 import android.graphics.Point;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.provider.Telephony;
30 import android.telecom.TelecomManager;
31 import android.text.BidiFormatter;
32 import android.text.TextDirectionHeuristics;
33 import android.text.TextUtils;
34 import android.view.View;
35 import android.view.inputmethod.InputMethodManager;
36 import android.widget.ImageView;
37 import android.widget.TextView;
38 import android.widget.Toast;
39 
40 import com.android.contacts.common.ContactsUtils;
41 import com.android.contacts.common.interactions.TouchPointManager;
42 import com.android.dialer.R;
43 import com.android.dialer.widget.EmptyContentView;
44 import com.android.incallui.CallCardFragment;
45 import com.android.incallui.Log;
46 
47 import java.util.ArrayList;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Locale;
51 
52 /**
53  * General purpose utility methods for the Dialer.
54  */
55 public class DialerUtils {
56 
57     /**
58      * Attempts to start an activity and displays a toast with the default error message if the
59      * activity is not found, instead of throwing an exception.
60      *
61      * @param context to start the activity with.
62      * @param intent to start the activity with.
63      */
startActivityWithErrorToast(Context context, Intent intent)64     public static void startActivityWithErrorToast(Context context, Intent intent) {
65         startActivityWithErrorToast(context, intent, R.string.activity_not_available);
66     }
67 
68     /**
69      * Attempts to start an activity and displays a toast with a provided error message if the
70      * activity is not found, instead of throwing an exception.
71      *
72      * @param context to start the activity with.
73      * @param intent to start the activity with.
74      * @param msgId Resource ID of the string to display in an error message if the activity is
75      *              not found.
76      */
startActivityWithErrorToast(Context context, Intent intent, int msgId)77     public static void startActivityWithErrorToast(Context context, Intent intent, int msgId) {
78         try {
79             if ((IntentUtil.CALL_ACTION.equals(intent.getAction())
80                             && context instanceof Activity)) {
81                 // All dialer-initiated calls should pass the touch point to the InCallUI
82                 Point touchPoint = TouchPointManager.getInstance().getPoint();
83                 if (touchPoint.x != 0 || touchPoint.y != 0) {
84                     Bundle extras = new Bundle();
85                     extras.putParcelable(TouchPointManager.TOUCH_POINT, touchPoint);
86                     intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras);
87                 }
88                 final TelecomManager tm =
89                         (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
90                 tm.placeCall(intent.getData(), intent.getExtras());
91             } else {
92                 context.startActivity(intent);
93             }
94         } catch (ActivityNotFoundException e) {
95             Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show();
96         }
97     }
98 
99     /**
100      * Returns the component name to use in order to send an SMS using the default SMS application,
101      * or null if none exists.
102      */
getSmsComponent(Context context)103     public static ComponentName getSmsComponent(Context context) {
104         String smsPackage = Telephony.Sms.getDefaultSmsPackage(context);
105         if (smsPackage != null) {
106             final PackageManager packageManager = context.getPackageManager();
107             final Intent intent = new Intent(Intent.ACTION_SENDTO,
108                     Uri.fromParts(ContactsUtils.SCHEME_SMSTO, "", null));
109             final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
110             for (ResolveInfo resolveInfo : resolveInfos) {
111                 if (smsPackage.equals(resolveInfo.activityInfo.packageName)) {
112                     return new ComponentName(smsPackage, resolveInfo.activityInfo.name);
113                 }
114             }
115         }
116         return null;
117     }
118 
119     /**
120      * Closes an {@link AutoCloseable}, silently ignoring any checked exceptions. Does nothing if
121      * null.
122      *
123      * @param closeable to close.
124      */
closeQuietly(AutoCloseable closeable)125     public static void closeQuietly(AutoCloseable closeable) {
126         if (closeable != null) {
127             try {
128                 closeable.close();
129             } catch (RuntimeException rethrown) {
130                 throw rethrown;
131             } catch (Exception ignored) {
132             }
133         }
134     }
135 
136     /**
137      * Joins a list of {@link CharSequence} into a single {@link CharSequence} seperated by a
138      * localized delimiter such as ", ".
139      *
140      * @param resources Resources used to get list delimiter.
141      * @param list List of char sequences to join.
142      * @return Joined char sequences.
143      */
join(Resources resources, Iterable<CharSequence> list)144     public static CharSequence join(Resources resources, Iterable<CharSequence> list) {
145         StringBuilder sb = new StringBuilder();
146         final BidiFormatter formatter = BidiFormatter.getInstance();
147         final CharSequence separator = resources.getString(R.string.list_delimeter);
148 
149         Iterator<CharSequence> itr = list.iterator();
150         boolean firstTime = true;
151         while (itr.hasNext()) {
152             if (firstTime) {
153                 firstTime = false;
154             } else {
155                 sb.append(separator);
156             }
157             // Unicode wrap the elements of the list to respect RTL for individual strings.
158             sb.append(formatter.unicodeWrap(
159                     itr.next().toString(), TextDirectionHeuristics.FIRSTSTRONG_LTR));
160         }
161 
162         // Unicode wrap the joined value, to respect locale's RTL ordering for the whole list.
163         return formatter.unicodeWrap(sb.toString());
164     }
165 
166     /**
167      * @return True if the application is currently in RTL mode.
168      */
isRtl()169     public static boolean isRtl() {
170         return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) ==
171             View.LAYOUT_DIRECTION_RTL;
172     }
173 
showInputMethod(View view)174     public static void showInputMethod(View view) {
175         final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
176                 Context.INPUT_METHOD_SERVICE);
177         if (imm != null) {
178             imm.showSoftInput(view, 0);
179         }
180     }
181 
hideInputMethod(View view)182     public static void hideInputMethod(View view) {
183         final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
184                 Context.INPUT_METHOD_SERVICE);
185         if (imm != null) {
186             imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
187         }
188     }
189 }
190