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

Commit 322ae005 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Move SMS message loading and sending to background thread to fix ANRs.

Flag: com.android.server.telecom.flags.enable_respond_via_sms_manager_async
Bug: 391790747
Test: Manually tested and unit tests
Change-Id: I04278d9901a2dc75c4a162faad7afc095c859fc0
parent 799c44b0
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -66,3 +66,14 @@ flag {
      purpose: PURPOSE_BUGFIX
    }
}

# OWNER=breadley TARGET=25Q2
flag {
  name: "enable_respond_via_sms_manager_async"
  namespace: "telecom"
  description: "Move RespondViaSmsManager to async thread"
  bug: "328013578"
  metadata {
      purpose: PURPOSE_BUGFIX
    }
}
+96 −43
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Looper;
import android.telecom.Connection;
import android.telecom.Log;
import android.telecom.Logging.Session;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
@@ -36,9 +38,13 @@ import android.text.SpannableString;
import android.text.TextUtils;
import android.widget.Toast;

import com.android.server.telecom.flags.FeatureFlags;

import java.text.Bidi;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

/**
 * Helper class to manage the "Respond via Message" feature for incoming calls.
@@ -74,10 +80,15 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {

    private final CallsManager mCallsManager;
    private final TelecomSystem.SyncRoot mLock;
    private final Executor mAsyncExecutor;
    private final FeatureFlags mFeatureFlags;

    public RespondViaSmsManager(CallsManager callsManager, TelecomSystem.SyncRoot lock) {
    public RespondViaSmsManager(CallsManager callsManager, TelecomSystem.SyncRoot lock,
        Executor asyncExecutor, FeatureFlags featureFlags) {
        mCallsManager = callsManager;
        mLock = lock;
        mAsyncExecutor = asyncExecutor;
        mFeatureFlags = featureFlags;
    }

    /**
@@ -93,11 +104,42 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {
     */
    public void loadCannedTextMessages(final CallsManager.Response<Void, List<String>> response,
            final Context context) {
        if (mFeatureFlags.enableRespondViaSmsManagerAsync()) {
            CompletableFuture<List<String>> cannedTextMessages = new CompletableFuture<>();
            Session s = Log.createSubsession();
            mAsyncExecutor.execute(() -> {
                try {
                    Log.continueSession(s, "RVSM.lCTM.e");
                    cannedTextMessages.complete(loadCannedTextMessages(context));
                } finally {
                    Log.endSession();
                }
            });
            cannedTextMessages.whenCompleteAsync((result, exception) -> {
                    if (exception != null) {
                        Log.e(RespondViaSmsManager.class.getSimpleName(), exception,
                                "loadCannedTextMessages failed");
                        response.onError(null, -1, exception.toString());
                    } else {
                        response.onResult(null, result);
                    }
                }, new LoggedHandlerExecutor(context.getMainThreadHandler(), "RVSM.lCTM.c", mLock));

        } else {
          new Thread() {
                @Override
                public void run() {
                Log.d(RespondViaSmsManager.this, "loadCannedResponses() starting");
                    List<String> textMessages = loadCannedTextMessages(context);
                    synchronized (mLock) {
                        response.onResult(null, textMessages);
                    }
                }
            }.start();
        }
    }

    private List<String> loadCannedTextMessages(final Context context) {
        Log.d(RespondViaSmsManager.this, "loadCannedTextMessages() starting");
        // This function guarantees that QuickResponses will be in our
        // SharedPreferences with the proper values considering there may be
        // old QuickResponses in Telephony pre L.
@@ -130,12 +172,7 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {
        Log.d(RespondViaSmsManager.this,
                "loadCannedResponses() completed, found responses: %s",
                textMessages.toString());

                synchronized (mLock) {
                    response.onResult(null, textMessages);
                }
            }
        }.start();
        return textMessages;
    }

    @Override
@@ -199,7 +236,23 @@ public class RespondViaSmsManager extends CallsManagerListenerBase {
                    subId);
            return;
        }
        if(mFeatureFlags.enableRespondViaSmsManagerAsync()) {
            Session s = Log.createSubsession();
            mAsyncExecutor.execute(() -> {
                try {
                    Log.continueSession(s, "RVSM.rCWM.e");
                    sendTextMessage(context, phoneNumber, textMessage, subId, contactName);
                } finally {
                    Log.endSession();
                }
            });
        } else {
            sendTextMessage(context, phoneNumber, textMessage, subId, contactName);
        }
    }

    private void sendTextMessage(Context context, String phoneNumber, String textMessage,
            int subId, String contactName) {
        SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
        try {
            ArrayList<String> messageParts = smsManager.divideMessage(textMessage);
+2 −1
Original line number Diff line number Diff line
@@ -462,7 +462,8 @@ public class TelecomSystem {
            });
            mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);

            mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
            mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock,
                asyncTaskExecutor, featureFlags);
            mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);

            mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,