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

Commit 7acab96e authored by Thomas Stuart's avatar Thomas Stuart
Browse files

Removed gated notif. + refactor ICC#gDDC

It was noted that the argument Binder.getCallingUid to
InCallController#getDefaultDialerComponent was incorrect
leading to the crash notification to be shown on every
target sdk.

However,when running tests manually with the correct argument
(DefaultPhoneAppName), on test apps targeting T,the RoleManager
would kick the test DefaultPhoneApp off of the Role#Dialer.  This
made the crash notification useless since the if clause would never
be entered.

Therefore, the crash notification code has been removed and a
refactor was done on the getDefaultDialer method to make the
logic more clear.

bug: 226186102
Test: 2 modified, 1 removed
Change-Id: Ib356e42b1747fc6e06bd0f216b88ef96be2ef283
parent 699de70a
Loading
Loading
Loading
Loading
+22 −28
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.os.Process.myUid;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.app.Notification;
@@ -90,17 +91,6 @@ public class InCallController extends CallsManagerListenerBase implements
        AppOpsManager.OnOpActiveChangedListener {
    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
@@ -1622,27 +1612,31 @@ public class InCallController extends CallsManagerListenerBase implements
        mNonUIInCallServiceConnections.connect(call);
    }

    private InCallServiceInfo getDefaultDialerComponent() {
        String packageName = mDefaultDialerCache.getDefaultDialerApplication(
    private @Nullable InCallServiceInfo getDefaultDialerComponent() {
        String defaultPhoneAppName = mDefaultDialerCache.getDefaultDialerApplication(
                mCallsManager.getCurrentUserHandle().getIdentifier());
        String systemPackageName = mDefaultDialerCache.getSystemDialerApplication();
        Log.d(this, "Default Dialer package: " + packageName);

        InCallServiceInfo defaultDialerComponent =
                (systemPackageName != null && systemPackageName.equals(packageName))
                        ? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI,
                        true /* ignoreDisabled */)
                        : getInCallServiceComponent(packageName,
        String systemPhoneAppName = mDefaultDialerCache.getSystemDialerApplication();

        Log.d(this, "getDefaultDialerComponent: defaultPhoneAppName=[%s]", defaultPhoneAppName);
        Log.d(this, "getDefaultDialerComponent: systemPhoneAppName=[%s]", systemPhoneAppName);

        // Get the defaultPhoneApp InCallService component...
        InCallServiceInfo defaultPhoneAppComponent =
                (systemPhoneAppName != null && systemPhoneAppName.equals(defaultPhoneAppName)) ?
                        /* The defaultPhoneApp is also the systemPhoneApp. Get systemPhoneApp info*/
                        getInCallServiceComponent(defaultPhoneAppName,
                                IN_CALL_SERVICE_TYPE_SYSTEM_UI, true /* ignoreDisabled */)
                        /* The defaultPhoneApp is NOT the systemPhoneApp. Get defaultPhoneApp info*/
                        : getInCallServiceComponent(defaultPhoneAppName,
                                IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI, true /* ignoreDisabled */);

        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);
        }
        Log.d(this, "getDefaultDialerComponent: defaultPhoneAppComponent=[%s]",
                defaultPhoneAppComponent);

        // defaultPhoneAppComponent is null in the case when the defaultPhoneApp does not implement
        // the InCallService && is the package is different from the systemPhoneApp

        return defaultDialerComponent;
        return defaultPhoneAppComponent;
    }

    private InCallServiceInfo getCurrentCarModeComponent() {
+2 −68
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -917,13 +918,10 @@ public class InCallControllerTests extends TelecomTestCase {

   /**
     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
     * 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.
     * supports third party app.
     */
    @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)
@@ -967,9 +965,6 @@ public class InCallControllerTests extends TelecomTestCase {
            // 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 sent by NotificationManager
            verify(mNotificationManager, times(1)).notify(eq(InCallController.NOTIFICATION_TAG),
                    eq(InCallController.IN_CALL_SERVICE_NOTIFICATION_ID), any());
        } finally {
            mockitoSession.finishMocking();
        }
@@ -1017,67 +1012,6 @@ 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 {