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

Commit 8d5d9742 authored by Matías Hernández's avatar Matías Hernández Committed by Android Build Coastguard Worker
Browse files

Fix getPackagesBypassingDnd() for multiple profiles

Despite what its name indicates, PackagePreferences.userId is almost always empty (0). This meant that getPackagesBypassingDnd() would treat all packages as belonging to USER_SYSTEM when looking app which apps have priority channels! In the Settings UI, this manifested as the personal-profile entry of the app appearing when the work-profile entry is the one that has priority channels (and the app not appearing at all if it's not installed in the personal profile).

Fixed the check and renamed the field, since this is a gigantic footgun.

Fixes: 384714165
Test: atest PreferencesHelperTest + manual
Flag: android.app.modes_ui
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ac0267dba7591b5b1ef8519a2f04126cb7e5b013)
Merged-In: I01c0b4efd435a1fada1bd9845044600c01c0baf6
Change-Id: I01c0b4efd435a1fada1bd9845044600c01c0baf6
parent 6b22d1c0
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -559,7 +559,7 @@ public class PreferencesHelper implements RankingConfig {

            if (r.uid == UNKNOWN_UID) {
                if (Flags.persistIncompleteRestoreData()) {
                    r.userId = userId;
                    r.userIdWhenUidUnknown = userId;
                }
                mRestoredWithoutUids.put(unrestoredPackageKey(pkg, userId), r);
            } else {
@@ -756,7 +756,7 @@ public class PreferencesHelper implements RankingConfig {

        if (Flags.persistIncompleteRestoreData() && r.uid == UNKNOWN_UID) {
            out.attributeLong(null, ATT_CREATION_TIME, r.creationTime);
            out.attributeInt(null, ATT_USERID, r.userId);
            out.attributeInt(null, ATT_USERID, r.userIdWhenUidUnknown);
        }

        if (!forBackup) {
@@ -1959,7 +1959,7 @@ public class PreferencesHelper implements RankingConfig {
        ArrayList<ZenBypassingApp> bypassing = new ArrayList<>();
        synchronized (mLock) {
            for (PackagePreferences p : mPackagePreferences.values()) {
                if (p.userId != userId) {
                if (UserHandle.getUserId(p.uid) != userId) {
                    continue;
                }
                int totalChannelCount = p.channels.size();
@@ -3189,7 +3189,7 @@ public class PreferencesHelper implements RankingConfig {
        // Until we enable the UI, we should return false.
        boolean canHavePromotedNotifs = android.app.Flags.uiRichOngoing();

        @UserIdInt int userId;
        @UserIdInt int userIdWhenUidUnknown;

        Delegate delegate = null;
        ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
+32 −5
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.No
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
import static com.android.server.notification.Flags.FLAG_NOTIFICATION_VERIFY_CHANNEL_SOUND_URI;
import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA;
import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER;
@@ -155,7 +154,6 @@ import android.util.proto.ProtoOutputStream;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.internal.config.sysui.TestableFlagResolver;
@@ -167,9 +165,6 @@ import com.android.os.AtomsProto.PackageNotificationPreferences;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.PermissionHelper.PackagePermission;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -204,6 +199,9 @@ import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

@SmallTest
@RunWith(ParameterizedAndroidJunit4.class)
@EnableFlags(FLAG_PERSIST_INCOMPLETE_RESTORE_DATA)
@@ -2639,6 +2637,35 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        assertThat(mHelper.getPackagesBypassingDnd(UserHandle.getUserId(UID_N_MR1))).isEmpty();
    }

    @Test
    public void getPackagesBypassingDnd_multipleUsers() {
        int uidUser1 = UserHandle.getUid(1, UID_P);
        NotificationChannel channelUser1Bypass = new NotificationChannel("id11", "name1",
                NotificationManager.IMPORTANCE_MAX);
        channelUser1Bypass.setBypassDnd(true);
        NotificationChannel channelUser1NoBypass = new NotificationChannel("id12", "name2",
                NotificationManager.IMPORTANCE_MAX);
        channelUser1NoBypass.setBypassDnd(false);

        int uidUser2 = UserHandle.getUid(2, UID_P);
        NotificationChannel channelUser2Bypass = new NotificationChannel("id21", "name1",
                NotificationManager.IMPORTANCE_MAX);
        channelUser2Bypass.setBypassDnd(true);

        mHelper.createNotificationChannel(PKG_P, uidUser1, channelUser1Bypass, true,
                /* hasDndAccess= */ true, uidUser1, false);
        mHelper.createNotificationChannel(PKG_P, uidUser1, channelUser1NoBypass, true,
                /* hasDndAccess= */ true, uidUser1, false);
        mHelper.createNotificationChannel(PKG_P, uidUser2, channelUser2Bypass, true,
                /* hasDndAccess= */ true, uidUser2, false);

        assertThat(mHelper.getPackagesBypassingDnd(0)).isEmpty();
        assertThat(mHelper.getPackagesBypassingDnd(1))
                .containsExactly(new ZenBypassingApp(PKG_P, false));
        assertThat(mHelper.getPackagesBypassingDnd(2))
                .containsExactly(new ZenBypassingApp(PKG_P, true));
    }

    @Test
    public void getPackagesBypassingDnd_oneChannelBypassing_groupBlocked() {
        int uid = UID_N_MR1;