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

Commit c7f313f3 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Add Coordinators to replace NotificationFilter"

parents 2764aa6b 8c80e0c8
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