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

Commit 4f4368b7 authored by Matías Hernández's avatar Matías Hernández Committed by Android (Google) Code Review
Browse files

Merge "Don't allow setting channels to bypass DND if the app cannot show...

Merge "Don't allow setting channels to bypass DND if the app cannot show notifications" into udc-dev
parents e4058d20 bf1b95e0
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;

import androidx.annotation.VisibleForTesting;
import androidx.core.text.BidiFormatter;
import androidx.lifecycle.LifecycleObserver;
import androidx.preference.Preference;
@@ -54,7 +55,7 @@ import java.util.List;
public class AppChannelsBypassingDndPreferenceController extends NotificationPreferenceController
        implements PreferenceControllerMixin, LifecycleObserver {

    private static final String KEY = "zen_mode_bypassing_app_channels_list";
    @VisibleForTesting static final String KEY = "zen_mode_bypassing_app_channels_list";
    private static final String ARG_FROM_SETTINGS = "fromSettings";

    private RestrictedSwitchPreference mAllNotificationsToggle;
@@ -74,8 +75,8 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
        mAllNotificationsToggle = new RestrictedSwitchPreference(mPreferenceCategory.getContext());
        mAllNotificationsToggle.setTitle(R.string.zen_mode_bypassing_app_channels_toggle_all);
        mAllNotificationsToggle.setDisabledByAdmin(mAdmin);
        mAllNotificationsToggle.setEnabled(
                (mAdmin == null || !mAllNotificationsToggle.isDisabledByAdmin()));
        mAllNotificationsToggle.setEnabled(!mAppRow.banned
                && (mAdmin == null || !mAllNotificationsToggle.isDisabledByAdmin()));
        mAllNotificationsToggle.setOnPreferenceClickListener(
                new Preference.OnPreferenceClickListener() {
                    @Override
@@ -206,6 +207,9 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
    }

    private boolean areAllChannelsBypassing() {
        if (mAppRow.banned) {
            return false;
        }
        boolean allChannelsBypassing = true;
        for (NotificationChannel channel : mChannels) {
            if (showNotification(channel)) {
@@ -226,7 +230,7 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
     * Whether notifications from this channel would show if DND weren't on.
     */
    private boolean showNotification(NotificationChannel channel) {
        return channel.getImportance() != IMPORTANCE_NONE;
        return !mAppRow.banned && channel.getImportance() != IMPORTANCE_NONE;
    }

    /**
+151 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.notification.app;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;

import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;

import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.PrimarySwitchPreference;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowApplication;

import java.util.ArrayList;
import java.util.Collections;

@RunWith(RobolectricTestRunner.class)
public class AppChannelsBypassingDndPreferenceControllerTest {

    @Mock
    private NotificationBackend mBackend;

    private NotificationBackend.AppRow mAppRow;
    private AppChannelsBypassingDndPreferenceController mController;

    private PreferenceScreen mPreferenceScreen;
    private PreferenceCategory mCategory;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        Context context = ApplicationProvider.getApplicationContext();

        mAppRow = new NotificationBackend.AppRow();
        mAppRow.uid = 42;
        mAppRow.pkg = "com.example.exampling";

        mController = new AppChannelsBypassingDndPreferenceController(context, mBackend);
        mController.onResume(mAppRow, null, null, null, null, null, new ArrayList<>());

        PreferenceManager preferenceManager = new PreferenceManager(context);
        mPreferenceScreen = preferenceManager.createPreferenceScreen(context);
        mCategory = new PreferenceCategory(context);
        mCategory.setKey(AppChannelsBypassingDndPreferenceController.KEY);
        mPreferenceScreen.addPreference(mCategory);
    }

    @Test
    public void displayPreference_showsAllAndChannels() {
        when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
                buildGroupList(true, true, false));

        mController.displayPreference(mPreferenceScreen);
        ShadowApplication.runBackgroundTasks();

        assertThat(mCategory.getPreferenceCount()).isEqualTo(4); // "All" + 3 channels
        assertThat(mCategory.getPreference(0).getTitle().toString()).isEqualTo(
                "Allow all notifications");
        assertThat(mCategory.getPreference(1).getTitle().toString()).isEqualTo("Channel 1");
        assertThat(mCategory.getPreference(2).getTitle().toString()).isEqualTo("Channel 2");
        assertThat(mCategory.getPreference(3).getTitle().toString()).isEqualTo("Channel 3");
    }

    @Test
    public void displayPreference_canToggleAllInterrupt() {
        when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
                buildGroupList(true, true, false));

        mController.displayPreference(mPreferenceScreen);
        ShadowApplication.runBackgroundTasks();

        assertThat(mCategory.getPreference(0).isEnabled()).isTrue();
    }

    @Test
    public void displayPreference_canToggleInterruptIfChannelEnabled() {
        when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
                buildGroupList(true, false, true));

        mController.displayPreference(mPreferenceScreen);
        ShadowApplication.runBackgroundTasks();

        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                1)).isSwitchEnabled()).isTrue();
        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                2)).isSwitchEnabled()).isFalse();
        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                3)).isSwitchEnabled()).isTrue();
    }

    @Test
    public void displayPreference_appBlocked_cannotToggleAllOrChannelInterrupts() {
        mAppRow.banned = true;
        when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
                buildGroupList(true, false, true));

        mController.displayPreference(mPreferenceScreen);
        ShadowApplication.runBackgroundTasks();

        assertThat(mCategory.getPreference(0).isEnabled()).isFalse();
        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                1)).isSwitchEnabled()).isFalse();
        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                2)).isSwitchEnabled()).isFalse();
        assertThat(((PrimarySwitchPreference) mCategory.getPreference(
                3)).isSwitchEnabled()).isFalse();
    }

    private static ParceledListSlice<NotificationChannelGroup> buildGroupList(
            boolean... enabledByChannel) {
        NotificationChannelGroup group = new NotificationChannelGroup("group", "The Group");
        for (int i = 0; i < enabledByChannel.length; i++) {
            group.addChannel(new NotificationChannel("channel-" + (i + 1), "Channel " + (i + 1),
                    enabledByChannel[i] ? NotificationManager.IMPORTANCE_DEFAULT
                            : NotificationManager.IMPORTANCE_NONE));
        }
        return new ParceledListSlice<>(Collections.singletonList(group));
    }
}