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

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

Merge "Removed gated notif. + refactor ICC#gDDC" into tm-dev

parents 2f8dccac 7acab96e
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 {