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

Commit 252b7fa6 authored by Thomas Stuart's avatar Thomas Stuart Committed by Android (Google) Code Review
Browse files

Merge "update when getDefaultDialerComponent sends a crash notif." into tm-dev

parents 6bafc444 3018d1dc
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -54,7 +54,8 @@ android_test {
        "androidx.legacy_legacy-support-core-utils",
        "androidx.core_core",
        "androidx.fragment_fragment",
        "androidx.test.ext.junit"
        "androidx.test.ext.junit",
        "platform-compat-test-rules",
    ],
    srcs: [
        "tests/src/**/*.java",
+19 −1
Original line number Diff line number Diff line
@@ -22,8 +22,11 @@ import static android.os.Process.myUid;
import android.Manifest;
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.app.Notification;
import android.app.NotificationManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -37,6 +40,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.hardware.SensorPrivacyManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -87,6 +91,16 @@ public class InCallController extends CallsManagerListenerBase implements
    public static final String NOTIFICATION_TAG = InCallController.class.getSimpleName();
    public static final int IN_CALL_SERVICE_NOTIFICATION_ID = 3;

    /**
     * Enable a crash notification if the default dialer app does not implement the
     * {@link InCallService} and the system Dialer takes over.
     *
     * @hide
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public static final long ENABLE_NOTIFICATION_FOR_DEFAULT_DIALER_CRASH = 218903401L; // bug id

    public class InCallServiceConnection {
        /**
         * Indicates that a call to {@link #connect(Call)} has succeeded and resulted in a
@@ -1620,10 +1634,14 @@ public class InCallController extends CallsManagerListenerBase implements
                        true /* ignoreDisabled */)
                        : getInCallServiceComponent(packageName,
                                IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI, true /* ignoreDisabled */);
        if (packageName != null && defaultDialerComponent == null) {

        if (packageName != null && defaultDialerComponent == null &&
                CompatChanges.isChangeEnabled(ENABLE_NOTIFICATION_FOR_DEFAULT_DIALER_CRASH,
                        Binder.getCallingUid())) {
            // The in call service of default phone app is disabled, send notification.
            sendCrashedInCallServiceNotification(packageName);
        }

        return defaultDialerComponent;
    }

+74 −1
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -102,7 +103,9 @@ import com.android.server.telecom.Timeouts;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
@@ -120,6 +123,8 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

import libcore.junit.util.compat.CoreCompatChangeRule;

@RunWith(JUnit4.class)
public class InCallControllerTests extends TelecomTestCase {
    @Mock CallsManager mMockCallsManager;
@@ -139,6 +144,9 @@ public class InCallControllerTests extends TelecomTestCase {
    @Mock NotificationManager mNotificationManager;
    @Mock PermissionInfo mMockPermissionInfo;

    @Rule
    public TestRule compatChangeRule = new PlatformCompatChangeRule();

    private static final int CURRENT_USER_ID = 900973;
    private static final String DEF_PKG = "defpkg";
    private static final String DEF_CLASS = "defcls";
@@ -909,10 +917,13 @@ public class InCallControllerTests extends TelecomTestCase {

   /**
     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
     * supports third party app
     * supports third party app.  Also, we want to verify a notification is sent to apps targeting
     * Tiramisu and above when the InCallService of the default app is disabled.
     */
    @MediumTest
    @Test
    @CoreCompatChangeRule.EnableCompatChanges({
            InCallController.ENABLE_NOTIFICATION_FOR_DEFAULT_DIALER_CRASH})
    public void testBindToService_ThirdPartyApp() throws Exception {
        final MockitoSession mockitoSession = ExtendedMockito.mockitoSession()
                .strictness(Strictness.WARN)
@@ -926,6 +937,7 @@ public class InCallControllerTests extends TelecomTestCase {

            ApplicationInfo applicationInfo = new ApplicationInfo();
            applicationInfo.targetSdkVersion = Build.VERSION_CODES.TIRAMISU;
            // set up mock call for ICSC#sendCrashedInCallServiceNotification(String)
            when(mMockContext.getApplicationInfo()).thenReturn(applicationInfo);

            // Enable Third Party Companion App
@@ -1005,6 +1017,67 @@ public class InCallControllerTests extends TelecomTestCase {
                eq(InCallController.IN_CALL_SERVICE_NOTIFICATION_ID), any());
    }

    /**
     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
     * supports third party app. Also, we want to verify a notification is NOT sent to apps
     * targeting below Tiramisu when the InCallService of the default app is disabled.
     */
    @MediumTest
    @Test
    @CoreCompatChangeRule.DisableCompatChanges({
            InCallController.ENABLE_NOTIFICATION_FOR_DEFAULT_DIALER_CRASH})
    public void testBindToService_ThirdPartyAppBelowTiramisu() throws Exception {
        final MockitoSession mockitoSession = ExtendedMockito.mockitoSession()
                .strictness(Strictness.WARN)
                .spyStatic(PermissionChecker.class)
                .startMocking();
        try {
            setupMocks(false /* isExternalCall */);
            setupMockPackageManager(false /* default */, false /* nonui */, true /* appop_nonui */,
                    true /* system */, false /* external calls */, false /* self mgd in default */,
                    false /* self mgd in car*/);

            ApplicationInfo applicationInfo = new ApplicationInfo();
            applicationInfo.targetSdkVersion = Build.VERSION_CODES.S_V2;
            // set up mock call for ICSC#sendCrashedInCallServiceNotification(String)
            when(mMockContext.getApplicationInfo()).thenReturn(applicationInfo);

            // Enable Third Party Companion App
            ExtendedMockito.doReturn(PermissionChecker.PERMISSION_GRANTED).when(() ->
                    PermissionChecker.checkPermissionForDataDeliveryFromDataSource(
                            any(Context.class), eq(Manifest.permission.MANAGE_ONGOING_CALLS),
                            anyInt(), any(AttributionSource.class), nullable(String.class)));

            // Now bind; we should bind to the system dialer and app op non ui app.
            mInCallController.bindToServices(mMockCall);

            // Bind InCallServices
            ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
            verify(mMockContext, times(2)).bindServiceAsUser(
                    bindIntentCaptor.capture(),
                    any(ServiceConnection.class),
                    eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
                            | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
                    eq(UserHandle.CURRENT));

            // Verify bind
            assertEquals(2, bindIntentCaptor.getAllValues().size());

            // Should have first bound to the system dialer.
            verifyBinding(bindIntentCaptor, 0, SYS_PKG, SYS_CLASS);

            // Should have next bound to the third party app op non ui app.
            verifyBinding(bindIntentCaptor, 1, APPOP_NONUI_PKG, APPOP_NONUI_CLASS);

            // Verify notification is NOT sent by NotificationManager
            verify(mNotificationManager, times(0)).notify(eq(InCallController.NOTIFICATION_TAG),
                    eq(InCallController.IN_CALL_SERVICE_NOTIFICATION_ID), any());

        } finally {
            mockitoSession.finishMocking();
        }
    }

    @MediumTest
    @Test
    public void testSanitizeContactName() throws Exception {