Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af74a5c4 authored by Hall Liu's avatar Hall Liu
Browse files

Use sendMultipartTextMessage for respond with sms

Long messages won't send properly if used in the respond-with-sms API.
Use sendMultipartTextMessage to get around this. Also display an error
toast if the message didn't send properly.

Bug: 65087120
Test: manual
Change-Id: I31ba24a0600e42010752b1216b1aca7d1098b319
parent d79e129b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
        android:sharedUserId="android.uid.system">

    <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION" />
    <protected-broadcast android:name="com.android.server.telecom.MESSAGE_SENT" />


    <!-- Prevents the activity manager from delaying any activity-start
         requests by this package, including requests immediately after
+4 −0
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@
        a text response. [CHAR LIMIT=40] -->
    <string name="respond_via_sms_confirmation_format">Message sent to <xliff:g id="phone_number">%s</xliff:g>.</string>

    <!-- "Respond via SMS": Error toast shown after failing to send
        a text response. [CHAR LIMIT=40] -->
    <string name="respond_via_sms_failure_format">Message failed to send to <xliff:g id="phone_number">%s</xliff:g>.</string>

    <!-- Title of settings screen that allows user to enable and disable phone-accounts.
         Each method for placing a call (SIM1, SIM2, SIP account, etc) has a phone-account.
         Phone-accounts that are created by third party apps can be disabled and enabled by user.
+49 −29
Original line number Diff line number Diff line
@@ -18,10 +18,14 @@ package com.android.server.telecom;

// TODO: Needed for move to system service: import com.android.internal.R;
import com.android.internal.os.SomeArgs;
import com.android.internal.telephony.SmsApplication;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Handler;
@@ -45,29 +49,36 @@ import java.util.List;
 * Helper class to manage the "Respond via Message" feature for incoming calls.
 */
public class RespondViaSmsManager extends CallsManagerListenerBase {
    private static final int MSG_SHOW_SENT_TOAST = 2;
    private static final String ACTION_MESSAGE_SENT = "com.android.server.telecom.MESSAGE_SENT";

    private final CallsManager mCallsManager;
    private final TelecomSystem.SyncRoot mLock;
    private static final class MessageSentReceiver extends BroadcastReceiver {
        private final String mContactName;
        private final int mNumMessageParts;
        private int mNumMessagesSent = 0;
        MessageSentReceiver(String contactName, int numMessageParts) {
            mContactName = contactName;
            mNumMessageParts = numMessageParts;
        }

    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SHOW_SENT_TOAST: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    try {
                        String toastMessage = (String) args.arg1;
                        Context context = (Context) args.arg2;
                        showMessageSentToast(toastMessage, context);
                    } finally {
                        args.recycle();
        public void onReceive(Context context, Intent intent) {
            if (getResultCode() == Activity.RESULT_OK) {
                mNumMessagesSent++;
                if (mNumMessagesSent == mNumMessageParts) {
                    showMessageResultToast(mContactName, context, true);
                    context.unregisterReceiver(this);
                }
                    break;
            } else {
                context.unregisterReceiver(this);
                showMessageResultToast(mContactName, context, false);
                Log.w(RespondViaSmsManager.class.getSimpleName(),
                        "Message failed with error %s", getResultCode());
            }
        }
    }
    };

    private final CallsManager mCallsManager;
    private final TelecomSystem.SyncRoot mLock;

    public RespondViaSmsManager(CallsManager callsManager, TelecomSystem.SyncRoot lock) {
        mCallsManager = callsManager;
@@ -144,13 +155,15 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {
        }
    }

    private void showMessageSentToast(final String phoneNumber, final Context context) {
    private static void showMessageResultToast(final String phoneNumber,
            final Context context, boolean success) {
        // ...and show a brief confirmation to the user (since
        // otherwise it's hard to be sure that anything actually
        // happened.)
        final Resources res = context.getResources();
        final String formatString = res.getString(
                R.string.respond_via_sms_confirmation_format);
        final String formatString = res.getString(success
                ? R.string.respond_via_sms_confirmation_format
                : R.string.respond_via_sms_failure_format);
        final String confirmationMsg = String.format(formatString, phoneNumber);
        int startingPosition = confirmationMsg.indexOf(phoneNumber);
        int endingPosition = startingPosition + phoneNumber.length();
@@ -192,13 +205,20 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {

        SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
        try {
            smsManager.sendTextMessage(phoneNumber, null, textMessage, null /*sentIntent*/,
                    null /*deliveryIntent*/);

            SomeArgs args = SomeArgs.obtain();
            args.arg1 = !TextUtils.isEmpty(contactName) ? contactName : phoneNumber;
            args.arg2 = context;
            mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, args).sendToTarget();
            ArrayList<String> messageParts = smsManager.divideMessage(textMessage);
            ArrayList<PendingIntent> sentIntents = new ArrayList<>(messageParts.size());
            for (int i = 0; i < messageParts.size(); i++) {
                Intent intent = new Intent(ACTION_MESSAGE_SENT);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent,
                        PendingIntent.FLAG_ONE_SHOT);
                sentIntents.add(pendingIntent);
            }
            MessageSentReceiver receiver = new MessageSentReceiver(
                    !TextUtils.isEmpty(contactName) ? contactName : phoneNumber,
                    messageParts.size());
            context.registerReceiver(receiver, new IntentFilter(ACTION_MESSAGE_SENT));
            smsManager.sendMultipartTextMessage(phoneNumber, null, messageParts,
                    sentIntents/*sentIntent*/, null /*deliveryIntent*/);
        } catch (IllegalArgumentException e) {
            Log.w(RespondViaSmsManager.this, "Couldn't send SMS message: " +
                    e.getMessage());