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

Commit 8c80e0c8 authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Add Coordinators to replace NotificationFilter

Test: atest SystemUiTests
Bug: 145134683
Change-Id: Ibd6331c261f96c9ce5ab6c9c453473a7a349c8e8
parent af16ee0c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ import javax.inject.Singleton;
 */
@Singleton
public class ForegroundServiceController {
    private static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
    public static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
            AppOpsManager.OP_RECORD_AUDIO,
            AppOpsManager.OP_COARSE_LOCATION,
+23 −2
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.util.Log;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;

import javax.inject.Inject;
@@ -46,7 +48,8 @@ public class ForegroundServiceNotificationListener {
    @Inject
    public ForegroundServiceNotificationListener(Context context,
            ForegroundServiceController foregroundServiceController,
            NotificationEntryManager notificationEntryManager) {
            NotificationEntryManager notificationEntryManager,
            NotifCollection notifCollection) {
        mContext = context;
        mForegroundServiceController = foregroundServiceController;
        mEntryManager = notificationEntryManager;
@@ -69,8 +72,24 @@ public class ForegroundServiceNotificationListener {
                removeNotification(entry.getSbn());
            }
        });

        mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender());

        notifCollection.addCollectionListener(new NotifCollectionListener() {
            @Override
            public void onEntryAdded(NotificationEntry entry) {
                addNotification(entry, entry.getImportance());
            }

            @Override
            public void onEntryUpdated(NotificationEntry entry) {
                updateNotification(entry, entry.getImportance());
            }

            @Override
            public void onEntryRemoved(NotificationEntry entry, int reason, boolean removedByUser) {
                removeNotification(entry.getSbn());
            }
        });
    }

    /**
@@ -152,6 +171,8 @@ public class ForegroundServiceNotificationListener {
                true /* create if not found */);
    }

    // TODO: remove this when fully migrated to the NewNotifPipeline (work done in
    //  ForegroundCoordinator)
    private void tagForeground(NotificationEntry entry) {
        final StatusBarNotification sbn = entry.getSbn();
        ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import java.util.Arrays;
/**
 * Struct to track relevant packages and notifications for a userid's foreground services.
 */
class ForegroundServicesUserState {
public class ForegroundServicesUserState {
    // shelf life of foreground services before they go bad
    private static final long FG_SERVICE_GRACE_MILLIS = 5000;

+9 −4
Original line number Diff line number Diff line
@@ -275,10 +275,6 @@ public final class NotificationEntry extends ListEntry {
        return mRanking.getSuppressedVisualEffects();
    }

    public boolean isSuspended() {
        return mRanking.isSuspended();
    }

    /** @see Ranking#canBubble() */
    public boolean canBubble() {
        return mRanking.canBubble();
@@ -950,6 +946,15 @@ public final class NotificationEntry extends ListEntry {
        return Objects.equals(n.category, category);
    }

    /**
     * Whether or not this row represents a system notification. Note that if this is
     * {@code null}, that means we were either unable to retrieve the info or have yet to
     * retrieve the info.
     */
    public Boolean isSystemNotification() {
        return mIsSystemNotification;
    }

    /**
     * Set this notification to be sensitive.
     *
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.systemui.statusbar.notification.collection.coordinator;

import android.Manifest;
import android.app.AppGlobals;
import android.app.Notification;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;

import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * Filters out most notifications when the device is unprovisioned.
 * Special notifications with extra permissions and tags won't be filtered out even when the
 * device is unprovisioned.
 */
@Singleton
public class DeviceProvisionedCoordinator implements Coordinator {
    private static final String TAG = "DeviceProvisionedCoordinator";

    private final DeviceProvisionedController mDeviceProvisionedController;

    @Inject
    public DeviceProvisionedCoordinator(DeviceProvisionedController deviceProvisionedController) {
        mDeviceProvisionedController = deviceProvisionedController;
    }

    @Override
    public void attach(NotifCollection notifCollection, NotifListBuilder notifListBuilder) {
        mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);

        notifListBuilder.addFilter(mNotifFilter);
    }

    protected final NotifFilter mNotifFilter = new NotifFilter(TAG) {
        @Override
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
            return !mDeviceProvisionedController.isDeviceProvisioned()
                    && !showNotificationEvenIfUnprovisioned(entry.getSbn());
        }
    };

    /**
     * Only notifications coming from packages with permission
     * android.permission.NOTIFICATION_DURING_SETUP that also have special tags
     * marking them as relevant for setup are allowed to show when device is unprovisioned
     */
    private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
        final boolean hasPermission = checkUidPermission(AppGlobals.getPackageManager(),
                Manifest.permission.NOTIFICATION_DURING_SETUP,
                sbn.getUid()) == PackageManager.PERMISSION_GRANTED;
        return hasPermission
                && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
    }

    private static int checkUidPermission(IPackageManager packageManager, String permission,
            int uid) {
        try {
            return packageManager.checkUidPermission(permission, uid);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private final DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedListener =
            new DeviceProvisionedController.DeviceProvisionedListener() {
                @Override
                public void onDeviceProvisionedChanged() {
                    mNotifFilter.invalidateList();
                }
            };
}
Loading