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

Commit abb43335 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Sticky behavior is limited to apps that ask for permission

Test: PermissionHelperTest
Test: NotificationManagerServiceTest
Test: post notification that asked for FSI permission, sticky
Test: post notification that did not ask for FSI permission, not sticky
Fixes: 274676056
Change-Id: I7c18052359c79df14c55eed263fce954d7083aa7
parent 09cd89ce
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -6730,8 +6730,11 @@ public class NotificationManagerService extends SystemService {
        handleSavePolicyFile();
    }
    private void makeStickyHun(Notification notification) {
    private void makeStickyHun(Notification notification, String pkg, @UserIdInt int userId) {
        if (mPermissionHelper.hasRequestedPermission(
                Manifest.permission.USE_FULL_SCREEN_INTENT, pkg, userId)) {
            notification.flags |= FLAG_FSI_REQUESTED_BUT_DENIED;
        }
        if (notification.contentIntent == null) {
            // On notification click, if contentIntent is null, SystemUI launches the
            // fullScreenIntent instead.
@@ -6795,10 +6798,9 @@ public class NotificationManagerService extends SystemService {
                    SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI);
            if (forceDemoteFsiToStickyHun) {
                makeStickyHun(notification);
                makeStickyHun(notification, pkg, userId);
            } else if (showStickyHunIfDenied) {
                final AttributionSource source = new AttributionSource.Builder(notificationUid)
                        .setPackageName(pkg)
                        .build();
@@ -6807,7 +6809,7 @@ public class NotificationManagerService extends SystemService {
                        Manifest.permission.USE_FULL_SCREEN_INTENT, source, /* message= */ null);
                if (permissionResult != PermissionManager.PERMISSION_GRANTED) {
                    makeStickyHun(notification);
                    makeStickyHun(notification, pkg, userId);
                }
            } else {
+24 −0
Original line number Diff line number Diff line
@@ -77,6 +77,30 @@ public final class PermissionHelper {
        }
    }

    /**
     * Returns whether the given app requested the given permission. Must not be called
     * with a lock held.
     */
    public boolean hasRequestedPermission(String permission, String pkg, @UserIdInt int userId) {
        final long callingId = Binder.clearCallingIdentity();
        try {
            PackageInfo pi = mPackageManager.getPackageInfo(pkg, GET_PERMISSIONS, userId);
            if (pi == null || pi.requestedPermissions == null) {
                return false;
            }
            for (String perm : pi.requestedPermissions) {
                if (permission.equals(perm)) {
                    return true;
                }
            }
        } catch (RemoteException e) {
            Slog.d(TAG, "Could not reach system server", e);
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        return false;
    }

    /**
     * Returns all of the apps that have requested the notification permission in a given user.
     * Must not be called with a lock held. Format: uid, packageName
+20 −8
Original line number Diff line number Diff line
@@ -10462,8 +10462,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class));
    }

    private void verifyStickyHun(Flag flag, int permissionState, boolean isSticky)
            throws Exception {
    private void verifyStickyHun(Flag flag, int permissionState, boolean appRequested,
            boolean isSticky) throws Exception {

        when(mPermissionHelper.hasRequestedPermission(Manifest.permission.USE_FULL_SCREEN_INTENT,
                PKG, mUserId)).thenReturn(appRequested);

        mTestFlagResolver.setFlagOverride(flag, true);

@@ -10491,7 +10494,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            throws Exception {

        verifyStickyHun(/* flag= */ SHOW_STICKY_HUN_FOR_DENIED_FSI,
                /* permissionState= */ PermissionManager.PERMISSION_HARD_DENIED,
                /* permissionState= */ PermissionManager.PERMISSION_HARD_DENIED, true,
                /* isSticky= */ true);
    }

@@ -10500,16 +10503,25 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            throws Exception {

        verifyStickyHun(/* flag= */ SHOW_STICKY_HUN_FOR_DENIED_FSI,
                /* permissionState= */ PermissionManager.PERMISSION_SOFT_DENIED,
                /* permissionState= */ PermissionManager.PERMISSION_SOFT_DENIED, true,
                /* isSticky= */ true);
    }

    @Test
    public void testFixNotification_fsiPermissionSoftDenied_appNotRequest_noShowStickyHun()
            throws Exception {
        verifyStickyHun(/* flag= */ SHOW_STICKY_HUN_FOR_DENIED_FSI,
                /* permissionState= */ PermissionManager.PERMISSION_SOFT_DENIED, false,
                /* isSticky= */ false);
    }


    @Test
    public void testFixNotification_flagEnableStickyHun_fsiPermissionGranted_showFsi()
            throws Exception {

        verifyStickyHun(/* flag= */ SHOW_STICKY_HUN_FOR_DENIED_FSI,
                /* permissionState= */ PermissionManager.PERMISSION_GRANTED,
                /* permissionState= */ PermissionManager.PERMISSION_GRANTED, true,
                /* isSticky= */ false);
    }

@@ -10518,7 +10530,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            throws Exception {

        verifyStickyHun(/* flag= */ FSI_FORCE_DEMOTE,
                /* permissionState= */ PermissionManager.PERMISSION_HARD_DENIED,
                /* permissionState= */ PermissionManager.PERMISSION_HARD_DENIED, true,
                /* isSticky= */ true);
    }

@@ -10527,7 +10539,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            throws Exception {

        verifyStickyHun(/* flag= */ FSI_FORCE_DEMOTE,
                /* permissionState= */ PermissionManager.PERMISSION_SOFT_DENIED,
                /* permissionState= */ PermissionManager.PERMISSION_SOFT_DENIED, true,
                /* isSticky= */ true);
    }

@@ -10536,7 +10548,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            throws Exception {

        verifyStickyHun(/* flag= */ FSI_FORCE_DEMOTE,
                /* permissionState= */ PermissionManager.PERMISSION_GRANTED,
                /* permissionState= */ PermissionManager.PERMISSION_GRANTED, true,
                /* isSticky= */ true);
    }

+62 −0
Original line number Diff line number Diff line
@@ -137,6 +137,68 @@ public class PermissionHelperTest extends UiServiceTestCase {
        assertThat(actual).containsExactlyElementsIn(expected);
    }

    @Test
    public void testHasRequestedPermission_otherPermission() throws Exception {
        final String permission = "correct";

        String packageName = "testHasRequestedPermission_otherPermission";

        PackageInfo info = new PackageInfo();
        info.packageName = packageName;
        info.requestedPermissions = new String[]{"something else"};

        when(mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS, 0)).thenReturn(info);

        assertThat(mPermissionHelper.hasRequestedPermission(permission, packageName, 0)).isFalse();

    }

    @Test
    public void testHasRequestedPermission_noPermissions() throws Exception {
        final String permission = "correct";

        String packageName = "testHasRequestedPermission_noPermissions";

        PackageInfo info = new PackageInfo();
        info.packageName = packageName;

        when(mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS, 0)).thenReturn(info);

        assertThat(mPermissionHelper.hasRequestedPermission(permission, packageName, 0)).isFalse();
    }

    @Test
    public void testHasRequestedPermission_singlePermissions() throws Exception {
        final String permission = "correct";

        String packageName = "testHasRequestedPermission_twoPermissions";

        PackageInfo info = new PackageInfo();
        info.packageName = packageName;
        info.requestedPermissions =
                new String[]{permission};

        when(mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS, 0)).thenReturn(info);

        assertThat(mPermissionHelper.hasRequestedPermission(permission, packageName, 0)).isTrue();
    }

    @Test
    public void testHasRequestedPermission_twoPermissions() throws Exception {
        final String permission = "correct";

        String packageName = "testHasRequestedPermission_twoPermissions";

        PackageInfo info = new PackageInfo();
        info.packageName = packageName;
        info.requestedPermissions =
                new String[]{"something else", permission};

        when(mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS, 0)).thenReturn(info);

        assertThat(mPermissionHelper.hasRequestedPermission(permission, packageName, 0)).isTrue();
    }

    @Test
    public void testGetAppsGrantedPermission_noApps() throws Exception {
        int userId = 1;