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

Commit 58b32f89 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "The notification archive should follow history setting" into rvc-dev am: 64fb27fc

Change-Id: I04b874e737ffa3fa75ebf6c26c7dd0eb4227a1ae
parents 0a11a2cd 64fb27fc
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -292,6 +292,18 @@ public class StatusBarNotification implements Parcelable {
        return this.user.getIdentifier();
        return this.user.getIdentifier();
    }
    }


    /**
     * Like {@link #getUserId()} but handles special users.
     * @hide
     */
    public int getNormalizedUserId() {
        int userId = getUserId();
        if (userId == UserHandle.USER_ALL) {
            userId = UserHandle.USER_SYSTEM;
        }
        return userId;
    }

    /** The package that the notification belongs to. */
    /** The package that the notification belongs to. */
    public String getPackageName() {
    public String getPackageName() {
        return pkg;
        return pkg;
+38 −6
Original line number Original line Diff line number Diff line
@@ -108,6 +108,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.annotation.WorkerThread;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal;
@@ -221,6 +222,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.Pair;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.SparseArrayMap;
import android.util.StatsEvent;
import android.util.StatsEvent;
import android.util.Xml;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
@@ -292,6 +294,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.List;
import java.util.Map.Entry;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Objects;
@@ -529,13 +532,15 @@ public class NotificationManagerService extends SystemService {
    private NotificationRecordLogger mNotificationRecordLogger;
    private NotificationRecordLogger mNotificationRecordLogger;
    private InstanceIdSequence mNotificationInstanceIdSequence;
    private InstanceIdSequence mNotificationInstanceIdSequence;


    private static class Archive {
    static class Archive {
        final SparseArray<Boolean> mEnabled;
        final int mBufferSize;
        final int mBufferSize;
        final ArrayDeque<Pair<StatusBarNotification, Integer>> mBuffer;
        final LinkedList<Pair<StatusBarNotification, Integer>> mBuffer;


        public Archive(int size) {
        public Archive(int size) {
            mBufferSize = size;
            mBufferSize = size;
            mBuffer = new ArrayDeque<>(mBufferSize);
            mBuffer = new LinkedList<>();
            mEnabled = new SparseArray<>();
        }
        }


        public String toString() {
        public String toString() {
@@ -548,7 +553,10 @@ public class NotificationManagerService extends SystemService {
            return sb.toString();
            return sb.toString();
        }
        }


        public void record(StatusBarNotification nr, int reason) {
        public void record(StatusBarNotification sbn, int reason) {
            if (!mEnabled.get(sbn.getNormalizedUserId(), false)) {
                return;
            }
            if (mBuffer.size() == mBufferSize) {
            if (mBuffer.size() == mBufferSize) {
                mBuffer.removeFirst();
                mBuffer.removeFirst();
            }
            }
@@ -556,7 +564,7 @@ public class NotificationManagerService extends SystemService {
            // We don't want to store the heavy bits of the notification in the archive,
            // We don't want to store the heavy bits of the notification in the archive,
            // but other clients in the system process might be using the object, so we
            // but other clients in the system process might be using the object, so we
            // store a (lightened) copy.
            // store a (lightened) copy.
            mBuffer.addLast(new Pair<>(nr.cloneLight(), reason));
            mBuffer.addLast(new Pair<>(sbn.cloneLight(), reason));
        }
        }


        public Iterator<Pair<StatusBarNotification, Integer>> descendingIterator() {
        public Iterator<Pair<StatusBarNotification, Integer>> descendingIterator() {
@@ -578,6 +586,17 @@ public class NotificationManagerService extends SystemService {
            return  a.toArray(new StatusBarNotification[a.size()]);
            return  a.toArray(new StatusBarNotification[a.size()]);
        }
        }


        public void updateHistoryEnabled(@UserIdInt int userId, boolean enabled) {
            mEnabled.put(userId, enabled);

            if (!enabled) {
                for (int i = mBuffer.size() - 1; i >= 0; i--) {
                    if (userId == mBuffer.get(i).first.getNormalizedUserId()) {
                        mBuffer.remove(i);
                    }
                }
            }
        }
    }
    }


    void loadDefaultApprovedServices(int userId) {
    void loadDefaultApprovedServices(int userId) {
@@ -1639,6 +1658,9 @@ public class NotificationManagerService extends SystemService {
                = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
                = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
        private final Uri NOTIFICATION_RATE_LIMIT_URI
        private final Uri NOTIFICATION_RATE_LIMIT_URI
                = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
                = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
        private final Uri NOTIFICATION_HISTORY_ENABLED
                = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_HISTORY_ENABLED);



        SettingsObserver(Handler handler) {
        SettingsObserver(Handler handler) {
            super(handler);
            super(handler);
@@ -1654,10 +1676,12 @@ public class NotificationManagerService extends SystemService {
                    false, this, UserHandle.USER_ALL);
                    false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
                    false, this, UserHandle.USER_ALL);
                    false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(NOTIFICATION_HISTORY_ENABLED,
                    false, this, UserHandle.USER_ALL);
            update(null);
            update(null);
        }
        }


        @Override public void onChange(boolean selfChange, Uri uri) {
        @Override public void onChange(boolean selfChange, Uri uri, int userId) {
            update(uri);
            update(uri);
        }
        }


@@ -1682,6 +1706,14 @@ public class NotificationManagerService extends SystemService {
            if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
            if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
                mPreferencesHelper.updateBubblesEnabled();
                mPreferencesHelper.updateBubblesEnabled();
            }
            }
            if (uri == null || NOTIFICATION_HISTORY_ENABLED.equals(uri)) {
                final IntArray userIds = mUserProfiles.getCurrentProfileIds();

                for (int i = 0; i < userIds.size(); i++) {
                    mArchive.updateHistoryEnabled(userIds.get(i), Settings.Secure.getInt(resolver,
                            Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1);
                }
            }
        }
        }
    }
    }


+143 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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.server.notification;

import static android.os.UserHandle.USER_CURRENT;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;

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

import android.app.Notification;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;

import androidx.test.runner.AndroidJUnit4;

import com.android.server.UiServiceTestCase;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class ArchiveTest extends UiServiceTestCase {
    private static final int SIZE = 5;

    private NotificationManagerService.Archive mArchive;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mArchive = new NotificationManagerService.Archive(SIZE);
        mArchive.updateHistoryEnabled(USER_SYSTEM, true);
        mArchive.updateHistoryEnabled(USER_CURRENT, true);
    }

    private StatusBarNotification getNotification(String pkg, int id, UserHandle user) {
        Notification n = new Notification.Builder(getContext(), "test")
                .setContentTitle("A")
                .setWhen(1205)
                .build();
        return  new StatusBarNotification(
                pkg, pkg, id, null, 0, 0, n, user, null, System.currentTimeMillis());
    }


    @Test
    public void testRecordAndRead() {
        List<String> expected = new ArrayList<>();
        for (int i = 0; i < SIZE; i++) {
            StatusBarNotification sbn = getNotification("pkg" + i, i,
                    UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT));
            expected.add(sbn.getKey());
            mArchive.record(sbn, REASON_CANCEL);
        }

        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
        assertThat(actual).hasSize(expected.size());
        for (StatusBarNotification sbn : actual) {
            assertThat(expected).contains(sbn.getKey());
        }
    }

    @Test
    public void testRecordAndRead_overLimit() {
        List<String> expected = new ArrayList<>();
        for (int i = 0; i < (SIZE * 2); i++) {
            StatusBarNotification sbn = getNotification("pkg" + i, i, UserHandle.of(USER_SYSTEM));
            mArchive.record(sbn, REASON_CANCEL);
            if (i >= SIZE) {
                expected.add(sbn.getKey());
            }
        }

        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray((SIZE * 2), true));
        assertThat(actual).hasSize(expected.size());
        for (StatusBarNotification sbn : actual) {
            assertThat(expected).contains(sbn.getKey());
        }
    }

    @Test
    public void testDoesNotRecordIfHistoryDisabled() {
        mArchive.updateHistoryEnabled(USER_CURRENT, false);
        List<String> expected = new ArrayList<>();
        for (int i = 0; i < SIZE; i++) {
            StatusBarNotification sbn = getNotification("pkg" + i, i,
                    UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT));
            mArchive.record(sbn, REASON_CANCEL);
            if (i % 2 ==0) {
                expected.add(sbn.getKey());
            }
        }

        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
        assertThat(actual).hasSize(expected.size());
        for (StatusBarNotification sbn : actual) {
            assertThat(expected).contains(sbn.getKey());
        }
    }

    @Test
    public void testRemovesEntriesWhenHistoryDisabled() {
        mArchive.updateHistoryEnabled(USER_CURRENT, true);
        List<String> expected = new ArrayList<>();
        for (int i = 0; i < SIZE; i++) {
            StatusBarNotification sbn = getNotification("pkg" + i, i,
                    UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT));
            mArchive.record(sbn, REASON_CANCEL);
            if (i % 2 ==0) {
                expected.add(sbn.getKey());
            }
        }
        mArchive.updateHistoryEnabled(USER_CURRENT, false);

        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
        assertThat(actual).hasSize(expected.size());
        for (StatusBarNotification sbn : actual) {
            assertThat(expected).contains(sbn.getKey());
        }
    }
}