From 827a90fb309fd26f5b155c1ad612512011d58437 Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Thu, 17 Sep 2015 18:10:58 -0700 Subject: Wrap some privileged Telecom operations with permission checks If the Dialer is not the default dialer and does not have the CALL_PHONE permission, don't call TelecomManager methods that will cause SecurityExceptions. Bug: 20266292 Change-Id: I229dd045269a262632c4a911e2321203443de684 --- src/com/android/dialer/DialtactsActivity.java | 3 ++- .../android/dialer/dialpad/DialpadFragment.java | 9 ++++++-- src/com/android/dialer/util/DialerUtils.java | 15 ++++++------ src/com/android/dialer/util/TelecomUtil.java | 27 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index dbff276e5..127ec447b 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -83,6 +83,7 @@ import com.android.dialer.list.SmartDialSearchFragment; import com.android.dialer.list.SpeedDialFragment; import com.android.dialer.settings.DialerSettingsActivity; import com.android.dialer.util.IntentUtil; +import com.android.dialer.util.TelecomUtil; import com.android.dialer.util.IntentUtil.CallIntentBuilder; import com.android.dialer.util.DialerUtils; import com.android.dialer.widget.ActionBarController; @@ -1182,7 +1183,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } private boolean phoneIsInUse() { - return getTelecomManager().isInCall(); + return TelecomUtil.isInCall(this); } private boolean canIntentBeHandled(Intent intent) { diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index d2628da5e..54e4b8946 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -81,6 +81,7 @@ import com.android.dialer.R; import com.android.dialer.SpecialCharSequenceMgr; import com.android.dialer.calllog.PhoneAccountUtils; import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.TelecomUtil; import com.android.dialer.util.IntentUtil.CallIntentBuilder; import com.android.incallui.Call.LogState; import com.android.phone.common.CallLogAsync; @@ -1478,8 +1479,12 @@ public class DialpadFragment extends Fragment * @return true if the phone is "in use", meaning that at least one line * is active (ie. off hook or ringing or dialing, or on hold). */ - public boolean isPhoneInUse() { - return getTelecomManager().isInCall(); + private boolean isPhoneInUse() { + final Context context = getActivity(); + if (context != null) { + return TelecomUtil.isInCall(context); + } + return false; } /** diff --git a/src/com/android/dialer/util/DialerUtils.java b/src/com/android/dialer/util/DialerUtils.java index fbe14ba9e..8870f76e4 100644 --- a/src/com/android/dialer/util/DialerUtils.java +++ b/src/com/android/dialer/util/DialerUtils.java @@ -33,18 +33,12 @@ import android.text.TextDirectionHeuristics; import android.text.TextUtils; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.ImageView; -import android.widget.TextView; import android.widget.Toast; import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.interactions.TouchPointManager; import com.android.dialer.R; -import com.android.dialer.widget.EmptyContentView; -import com.android.incallui.CallCardFragment; -import com.android.incallui.Log; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -94,7 +88,14 @@ public class DialerUtils { } final TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); - tm.placeCall(intent.getData(), intent.getExtras()); + if (TelecomUtil.hasCallPhonePermission(context)) { + tm.placeCall(intent.getData(), intent.getExtras()); + } else { + // TODO: Make calling activity show request permission dialog and handle + // callback results appropriately. + Toast.makeText(context, "Cannot place call without Phone permission", + Toast.LENGTH_SHORT); + } } else { context.startActivity(intent); } diff --git a/src/com/android/dialer/util/TelecomUtil.java b/src/com/android/dialer/util/TelecomUtil.java index 1cd270c9b..43b9a72a3 100644 --- a/src/com/android/dialer/util/TelecomUtil.java +++ b/src/com/android/dialer/util/TelecomUtil.java @@ -26,6 +26,9 @@ import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.Log; +import java.util.ArrayList; +import java.util.List; + public class TelecomUtil { private static final String TAG = "TelecomUtil"; private static boolean sWarningLogged = false; @@ -78,6 +81,20 @@ public class TelecomUtil { return false; } + public static List getCallCapablePhoneAccounts(Context context) { + if (hasReadPhoneStatePermission(context)) { + return getTelecomManager(context).getCallCapablePhoneAccounts(); + } + return new ArrayList<>(); + } + + public static boolean isInCall(Context context) { + if (hasReadPhoneStatePermission(context)) { + return getTelecomManager(context).isInCall(); + } + return false; + } + public static Uri getCallLogUri(Context context) { return hasReadWriteVoicemailPermissions(context) ? Calls.CONTENT_URI_WITH_VOICEMAIL : Calls.CONTENT_URI; @@ -94,6 +111,16 @@ public class TelecomUtil { || hasPermission(context, Manifest.permission.MODIFY_PHONE_STATE); } + public static boolean hasReadPhoneStatePermission(Context context) { + return isDefaultDialer(context) + || hasPermission(context, Manifest.permission.READ_PHONE_STATE); + } + + public static boolean hasCallPhonePermission(Context context) { + return isDefaultDialer(context) + || hasPermission(context, Manifest.permission.CALL_PHONE); + } + private static boolean hasPermission(Context context, String permission) { return context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; -- cgit v1.2.3