Add reject via text capability to calls
* Add REJECT_VIA_TEXT capability to calls
* Move allowRespondViaSmsForCall to RejectWithTextManager
Bug: 10424370
Change-Id: I059550d82e3b44cc4cc42d5eb06e40551497f063
diff --git a/src/com/android/phone/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index 1b13280..72273ee 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -79,17 +79,16 @@
try {
CallResult result = mCallModeler.getCallWithId(callId);
if (result != null) {
- if (rejectWithMessage) {
- if (message != null) {
- mRejectWithTextMessageManager.rejectCallWithMessage(
- result.getConnection().getCall(), message);
- } else {
- mRejectWithTextMessageManager.rejectCallWithNewMessage(
- result.getConnection().getCall());
- }
- }
+ final String number = result.getConnection().getAddress();
Log.v(TAG, "Hanging up");
PhoneUtils.hangupRingingCall(result.getConnection().getCall());
+ if (rejectWithMessage) {
+ if (message != null) {
+ mRejectWithTextMessageManager.rejectCallWithMessage(number, message);
+ } else {
+ mRejectWithTextMessageManager.rejectCallWithNewMessage(number);
+ }
+ }
}
} catch (Exception e) {
Log.e(TAG, "Error during rejectCall().", e);
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 393e054..9c7b9dd 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -16,13 +16,7 @@
package com.android.phone;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSortedSet;
-
+import android.content.Context;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -40,11 +34,16 @@
import com.android.services.telephony.common.Call.Capabilities;
import com.android.services.telephony.common.Call.State;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
-import java.util.SortedSet;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -469,6 +468,7 @@
boolean canAddCall = false;
boolean canMergeCall = false;
boolean canSwapCall = false;
+ boolean canRespondViaText = false;
// only applies to active calls
if (callIsActive) {
@@ -477,6 +477,9 @@
canSwapCall = PhoneUtils.okToSwapCalls(mCallManager);
}
+ canRespondViaText = RejectWithTextMessageManager.allowRespondViaSmsForCall(call,
+ connection);
+
// special rules section!
// CDMA always has Add
if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
@@ -500,6 +503,10 @@
retval |= Capabilities.SWAP_CALLS;
}
+ if (canRespondViaText) {
+ retval |= Capabilities.RESPOND_VIA_TEXT;
+ }
+
return retval;
}
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 57006bb..8b67b77 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -3371,8 +3371,6 @@
// it to always act on the first ringing call.
Call ringingCall = mCM.getFirstActiveRingingCall();
- mRespondViaSmsManager.showRespondViaSmsPopup(ringingCall);
-
// Silence the ringer, since it would be distracting while you're trying
// to pick a response. (Note that we'll restart the ringer if you bail
// out of the popup, though; see RespondViaSmsCancelListener.)
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
index 59f2f32..1d08671 100644
--- a/src/com/android/phone/InCallTouchUi.java
+++ b/src/com/android/phone/InCallTouchUi.java
@@ -1189,48 +1189,6 @@
}
mIncomingCallWidget.setAlpha(1.0f);
- // Update the GlowPadView widget's targets based on the state of
- // the ringing call. (Specifically, we need to disable the
- // "respond via SMS" option for certain types of calls, like SIP
- // addresses or numbers with blocked caller-id.)
- final boolean allowRespondViaSms =
- RespondViaSmsManager.allowRespondViaSmsForCall(mInCallScreen, ringingCall);
- final int targetResourceId = allowRespondViaSms
- ? R.array.incoming_call_widget_3way_targets
- : R.array.incoming_call_widget_2way_targets;
- // The widget should be updated only when appropriate; if the previous choice can be reused
- // for this incoming call, we'll just keep using it. Otherwise we'll see UI glitch
- // everytime when this method is called during a single incoming call.
- if (targetResourceId != mIncomingCallWidget.getTargetResourceId()) {
- if (allowRespondViaSms) {
- // The GlowPadView widget is allowed to have all 3 choices:
- // Answer, Decline, and Respond via SMS.
- mIncomingCallWidget.setTargetResources(targetResourceId);
- mIncomingCallWidget.setTargetDescriptionsResourceId(
- R.array.incoming_call_widget_3way_target_descriptions);
- mIncomingCallWidget.setDirectionDescriptionsResourceId(
- R.array.incoming_call_widget_3way_direction_descriptions);
- } else {
- // You only get two choices: Answer or Decline.
- mIncomingCallWidget.setTargetResources(targetResourceId);
- mIncomingCallWidget.setTargetDescriptionsResourceId(
- R.array.incoming_call_widget_2way_target_descriptions);
- mIncomingCallWidget.setDirectionDescriptionsResourceId(
- R.array.incoming_call_widget_2way_direction_descriptions);
- }
-
- // This will be used right after this block.
- mIncomingCallWidgetShouldBeReset = true;
- }
- if (mIncomingCallWidgetShouldBeReset) {
- // Watch out: be sure to call reset() and setVisibility() *after*
- // updating the target resources, since otherwise the GlowPadView
- // widget will make the targets visible initially (even before you
- // touch the widget.)
- mIncomingCallWidget.reset(false);
- mIncomingCallWidgetShouldBeReset = false;
- }
-
// On an incoming call, if the layout is landscape, then align the "incoming call" text
// to the left, because the incomingCallWidget (black background with glowing ring)
// is aligned to the right and would cover the "incoming call" text.
diff --git a/src/com/android/phone/RejectWithTextMessageManager.java b/src/com/android/phone/RejectWithTextMessageManager.java
index 8324bd4..b03211a 100644
--- a/src/com/android/phone/RejectWithTextMessageManager.java
+++ b/src/com/android/phone/RejectWithTextMessageManager.java
@@ -32,7 +32,9 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
+import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -46,6 +48,7 @@
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.PhoneConstants;
+
import com.google.android.collect.Lists;
import java.util.ArrayList;
@@ -128,29 +131,6 @@
}
/**
- * @return true if the "Respond via SMS" feature should be enabled
- * for the specified incoming call.
- *
- * The general rule is that we *do* allow "Respond via SMS" except for
- * the few (relatively rare) cases where we know for sure it won't
- * work, namely:
- * - a bogus or blank incoming number
- * - a call from a SIP address
- * - a "call presentation" that doesn't allow the number to be revealed
- *
- * In all other cases, we allow the user to respond via SMS.
- *
- * Note that this behavior isn't perfect; for example we have no way
- * to detect whether the incoming call is from a landline (with most
- * networks at least), so we still enable this feature even though
- * SMSes to that number will silently fail.
- */
- public static boolean allowRespondViaSmsForCall(Context context, Call ringingCall) {
- // TODO(klp) implement this!
- return true;
- }
-
- /**
* Sends a text message without any interaction from the user.
*/
private void sendText(String phoneNumber, String message, ComponentName component) {
@@ -199,7 +179,7 @@
* Queries the System to determine what packages contain services that can handle the instant
* text response Action AND have permissions to do so.
*/
- private ArrayList<ComponentName> getPackagesWithInstantTextPermission() {
+ private static ArrayList<ComponentName> getPackagesWithInstantTextPermission() {
final PackageManager packageManager = PhoneGlobals.getInstance().getPackageManager();
final ArrayList<ComponentName> componentsWithPermission = new ArrayList<ComponentName>();
@@ -251,8 +231,8 @@
return intent;
}
- public void rejectCallWithNewMessage(Call call) {
- launchSmsCompose(call.getLatestConnection().getAddress());
+ public void rejectCallWithNewMessage(String number) {
+ launchSmsCompose(number);
}
private ComponentName getSmsService() {
@@ -302,15 +282,105 @@
}
- public void rejectCallWithMessage(Call call, String message) {
+ public void rejectCallWithMessage(final String number, String message) {
final ComponentName componentName = getSmsService();
if (componentName != null) {
- sendTextAndExit(call.getLatestConnection().getAddress(), message, componentName,
+ sendTextAndExit(number, message, componentName,
false);
}
}
+ /**
+ * @return true if the "Respond via SMS" feature should be enabled
+ * for the specified incoming call.
+ *
+ * The general rule is that we *do* allow "Respond via SMS" except for
+ * the few (relatively rare) cases where we know for sure it won't
+ * work, namely:
+ * - a bogus or blank incoming number
+ * - a call from a SIP address
+ * - a "call presentation" that doesn't allow the number to be revealed
+ *
+ * In all other cases, we allow the user to respond via SMS.
+ *
+ * Note that this behavior isn't perfect; for example we have no way
+ * to detect whether the incoming call is from a landline (with most
+ * networks at least), so we still enable this feature even though
+ * SMSes to that number will silently fail.
+ */
+ public static boolean allowRespondViaSmsForCall(
+ com.android.services.telephony.common.Call call, Connection conn) {
+ if (DBG) log("allowRespondViaSmsForCall(" + call + ")...");
+
+ // First some basic sanity checks:
+ if (call == null) {
+ Log.w(TAG, "allowRespondViaSmsForCall: null ringingCall!");
+ return false;
+ }
+ if (!(call.getState() == com.android.services.telephony.common.Call.State.INCOMING) &&
+ !(call.getState() ==
+ com.android.services.telephony.common.Call.State.CALL_WAITING)) {
+ // The call is in some state other than INCOMING or WAITING!
+ // (This should almost never happen, but it *could*
+ // conceivably happen if the ringing call got disconnected by
+ // the network just *after* we got it from the CallManager.)
+ Log.w(TAG, "allowRespondViaSmsForCall: ringingCall not ringing! state = "
+ + call.getState());
+ return false;
+ }
+
+ if (conn == null) {
+ // The call doesn't have any connections! (Again, this can
+ // happen if the ringing call disconnects at the exact right
+ // moment, but should almost never happen in practice.)
+ Log.w(TAG, "allowRespondViaSmsForCall: null Connection!");
+ return false;
+ }
+
+ // Check the incoming number:
+ final String number = conn.getAddress();
+ if (DBG) log("- number: '" + number + "'");
+ if (TextUtils.isEmpty(number)) {
+ Log.w(TAG, "allowRespondViaSmsForCall: no incoming number!");
+ return false;
+ }
+ if (PhoneNumberUtils.isUriNumber(number)) {
+ // The incoming number is actually a URI (i.e. a SIP address),
+ // not a regular PSTN phone number, and we can't send SMSes to
+ // SIP addresses.
+ // (TODO: That might still be possible eventually, though. Is
+ // there some SIP-specific equivalent to sending a text message?)
+ Log.i(TAG, "allowRespondViaSmsForCall: incoming 'number' is a SIP address.");
+ return false;
+ }
+
+ // Finally, check the "call presentation":
+ int presentation = conn.getNumberPresentation();
+ if (DBG) log("- presentation: " + presentation);
+ if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+ // PRESENTATION_RESTRICTED means "caller-id blocked".
+ // The user isn't allowed to see the number in the first
+ // place, so obviously we can't let you send an SMS to it.
+ Log.i(TAG, "allowRespondViaSmsForCall: PRESENTATION_RESTRICTED.");
+ return false;
+ }
+
+ // Allow the feature only when there's a destination for it.
+ if (getPackagesWithInstantTextPermission().size() < 1) {
+ return false;
+ }
+
+ // TODO: with some carriers (in certain countries) you *can* actually
+ // tell whether a given number is a mobile phone or not. So in that
+ // case we could potentially return false here if the incoming call is
+ // from a land line.
+
+ // If none of the above special cases apply, it's OK to enable the
+ // "Respond via SMS" feature.
+ return true;
+ }
+
private static void log(String msg) {
Log.d(TAG, msg);
}
diff --git a/src/com/android/phone/RespondViaSmsManager.java b/src/com/android/phone/RespondViaSmsManager.java
index c851471..ffce899 100644
--- a/src/com/android/phone/RespondViaSmsManager.java
+++ b/src/com/android/phone/RespondViaSmsManager.java
@@ -61,6 +61,7 @@
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.PhoneConstants;
+
import com.google.android.collect.Lists;
import java.util.ArrayList;
@@ -769,94 +770,6 @@
return responses;
}
- /**
- * @return true if the "Respond via SMS" feature should be enabled
- * for the specified incoming call.
- *
- * The general rule is that we *do* allow "Respond via SMS" except for
- * the few (relatively rare) cases where we know for sure it won't
- * work, namely:
- * - a bogus or blank incoming number
- * - a call from a SIP address
- * - a "call presentation" that doesn't allow the number to be revealed
- *
- * In all other cases, we allow the user to respond via SMS.
- *
- * Note that this behavior isn't perfect; for example we have no way
- * to detect whether the incoming call is from a landline (with most
- * networks at least), so we still enable this feature even though
- * SMSes to that number will silently fail.
- */
- public static boolean allowRespondViaSmsForCall(Context context, Call ringingCall) {
- if (DBG) log("allowRespondViaSmsForCall(" + ringingCall + ")...");
-
- // First some basic sanity checks:
- if (ringingCall == null) {
- Log.w(TAG, "allowRespondViaSmsForCall: null ringingCall!");
- return false;
- }
- if (!ringingCall.isRinging()) {
- // The call is in some state other than INCOMING or WAITING!
- // (This should almost never happen, but it *could*
- // conceivably happen if the ringing call got disconnected by
- // the network just *after* we got it from the CallManager.)
- Log.w(TAG, "allowRespondViaSmsForCall: ringingCall not ringing! state = "
- + ringingCall.getState());
- return false;
- }
- Connection conn = ringingCall.getLatestConnection();
- if (conn == null) {
- // The call doesn't have any connections! (Again, this can
- // happen if the ringing call disconnects at the exact right
- // moment, but should almost never happen in practice.)
- Log.w(TAG, "allowRespondViaSmsForCall: null Connection!");
- return false;
- }
-
- // Check the incoming number:
- final String number = conn.getAddress();
- if (DBG) log("- number: '" + number + "'");
- if (TextUtils.isEmpty(number)) {
- Log.w(TAG, "allowRespondViaSmsForCall: no incoming number!");
- return false;
- }
- if (PhoneNumberUtils.isUriNumber(number)) {
- // The incoming number is actually a URI (i.e. a SIP address),
- // not a regular PSTN phone number, and we can't send SMSes to
- // SIP addresses.
- // (TODO: That might still be possible eventually, though. Is
- // there some SIP-specific equivalent to sending a text message?)
- Log.i(TAG, "allowRespondViaSmsForCall: incoming 'number' is a SIP address.");
- return false;
- }
-
- // Finally, check the "call presentation":
- int presentation = conn.getNumberPresentation();
- if (DBG) log("- presentation: " + presentation);
- if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
- // PRESENTATION_RESTRICTED means "caller-id blocked".
- // The user isn't allowed to see the number in the first
- // place, so obviously we can't let you send an SMS to it.
- Log.i(TAG, "allowRespondViaSmsForCall: PRESENTATION_RESTRICTED.");
- return false;
- }
-
- // Allow the feature only when there's a destination for it.
- if (context.getPackageManager().resolveService(getInstantTextIntent(number, null, null) , 0)
- == null) {
- return false;
- }
-
- // TODO: with some carriers (in certain countries) you *can* actually
- // tell whether a given number is a mobile phone or not. So in that
- // case we could potentially return false here if the incoming call is
- // from a land line.
-
- // If none of the above special cases apply, it's OK to enable the
- // "Respond via SMS" feature.
- return true;
- }
-
private int getIconSize() {
if (mIconSize < 0) {
final ActivityManager am =