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

Commit 201cdd50 authored by Beverly's avatar Beverly
Browse files

Remove onBeforeNotificationAdded call

By moving where appOps of notifications gets set

When appOps change:
 StatusBar detects appOp change and propogates change to
 ForegroundServiceController which stores appOp change
 (in case notification hasn't been added yet).
 This controller will also update the appOps of the relevant
 pending/visible notification

When a notification is added/updated:
 ForegroundServiceNotificationListener updates the
 relevant notification's appOps

Test: atest NotificationEntryManagerTest NotificationDataTest
Test: atest ForegroundServiceControllerTest
Change-Id: I3af4a2cf599d3eba7a0ba6006b3919730e5e658a
parent cabc32d2
Loading
Loading
Loading
Loading
+39 −6
Original line number Diff line number Diff line
@@ -21,10 +21,13 @@ import android.util.ArraySet;
import android.util.SparseArray;

import com.android.internal.messages.nano.SystemMessageProto;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;

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


/**
 * Tracks state of foreground services and notifications related to foreground services per user.
 */
@@ -33,9 +36,11 @@ public class ForegroundServiceController {

    private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
    private final Object mMutex = new Object();
    private final NotificationEntryManager mEntryManager;

    @Inject
    public ForegroundServiceController() {
    public ForegroundServiceController(NotificationEntryManager entryManager) {
        mEntryManager = entryManager;
    }

    /**
@@ -90,11 +95,18 @@ public class ForegroundServiceController {
    }

    /**
     * Records active app ops. App Ops are stored in FSC in addition to NotificationData in
     * case they change before we have a notification to tag.
     * Records active app ops and updates the app op for the pending or visible notifications
     * with the given parameters.
     * App Ops are stored in FSC in addition to NotificationEntry in case they change before we
     * have a notification to tag.
     * @param appOpCode code for appOp to add/remove
     * @param uid of user the notification is sent to
     * @param packageName package that created the notification
     * @param active whether the appOpCode is active or not
     */
    public void onAppOpChanged(int code, int uid, String packageName, boolean active) {
    public void onAppOpChanged(int appOpCode, int uid, String packageName, boolean active) {
        int userId = UserHandle.getUserId(uid);
        // Record active app ops
        synchronized (mMutex) {
            ForegroundServicesUserState userServices = mUserServices.get(userId);
            if (userServices == null) {
@@ -102,9 +114,30 @@ public class ForegroundServiceController {
                mUserServices.put(userId, userServices);
            }
            if (active) {
                userServices.addOp(packageName, code);
                userServices.addOp(packageName, appOpCode);
            } else {
                userServices.removeOp(packageName, code);
                userServices.removeOp(packageName, appOpCode);
            }
        }

        // Update appOp if there's an associated pending or visible notification:
        final String foregroundKey = getStandardLayoutKey(userId, packageName);
        if (foregroundKey != null) {
            final NotificationEntry entry = mEntryManager.getPendingOrCurrentNotif(foregroundKey);
            if (entry != null
                    && uid == entry.getSbn().getUid()
                    && packageName.equals(entry.getSbn().getPackageName())) {
                boolean changed;
                synchronized (entry.mActiveAppOps) {
                    if (active) {
                        changed = entry.mActiveAppOps.add(appOpCode);
                    } else {
                        changed = entry.mActiveAppOps.remove(appOpCode);
                    }
                }
                if (changed) {
                    mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
                }
            }
        }
    }
+28 −11
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.statusbar.NotificationVisibility;
@@ -40,6 +41,7 @@ public class ForegroundServiceNotificationListener {

    private final Context mContext;
    private final ForegroundServiceController mForegroundServiceController;
    private final NotificationEntryManager mEntryManager;

    @Inject
    public ForegroundServiceNotificationListener(Context context,
@@ -47,15 +49,16 @@ public class ForegroundServiceNotificationListener {
            NotificationEntryManager notificationEntryManager) {
        mContext = context;
        mForegroundServiceController = foregroundServiceController;
        notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
        mEntryManager = notificationEntryManager;
        mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
            @Override
            public void onPendingEntryAdded(NotificationEntry entry) {
                addNotification(entry.getSbn(), entry.getImportance());
                addNotification(entry, entry.getImportance());
            }

            @Override
            public void onPostEntryUpdated(NotificationEntry entry) {
                updateNotification(entry.getSbn(), entry.getImportance());
            public void onPreEntryUpdated(NotificationEntry entry) {
                updateNotification(entry, entry.getImportance());
            }

            @Override
@@ -67,15 +70,14 @@ public class ForegroundServiceNotificationListener {
            }
        });

        notificationEntryManager.addNotificationLifetimeExtender(
                new ForegroundServiceLifetimeExtender());
        mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender());
    }

    /**
     * @param sbn notification that was just posted
     * @param entry notification that was just posted
     */
    private void addNotification(StatusBarNotification sbn, int importance) {
        updateNotification(sbn, importance);
    private void addNotification(NotificationEntry entry, int importance) {
        updateNotification(entry, importance);
    }

    /**
@@ -113,9 +115,10 @@ public class ForegroundServiceNotificationListener {
    }

    /**
     * @param sbn notification that was just changed in some way
     * @param entry notification that was just changed in some way
     */
    private void updateNotification(StatusBarNotification sbn, int newImportance) {
    private void updateNotification(NotificationEntry entry, int newImportance) {
        final StatusBarNotification sbn = entry.getSbn();
        mForegroundServiceController.updateUserState(
                sbn.getUserId(),
                userState -> {
@@ -143,8 +146,22 @@ public class ForegroundServiceNotificationListener {
                            }
                        }
                    }
                    tagForeground(entry);
                    return true;
                },
                true /* create if not found */);
    }

    private void tagForeground(NotificationEntry entry) {
        final StatusBarNotification sbn = entry.getSbn();
        ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
                sbn.getUserId(),
                sbn.getPackageName());
        if (activeOps != null) {
            synchronized (entry.mActiveAppOps) {
                entry.mActiveAppOps.clear();
                entry.mActiveAppOps.addAll(activeOps);
            }
        }
    }
}
+2 −9
Original line number Diff line number Diff line
@@ -20,12 +20,12 @@ import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;

import androidx.annotation.NonNull;

import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;

import androidx.annotation.NonNull;

/**
 * Listener interface for changes sent by NotificationEntryManager.
 */
@@ -37,13 +37,6 @@ public interface NotificationEntryListener {
    default void onPendingEntryAdded(NotificationEntry entry) {
    }

    // TODO: Combine this with onPreEntryUpdated into "onBeforeEntryFiltered" or similar
    /**
     * Called when a new entry is created but before it has been filtered or displayed to the user.
     */
    default void onBeforeNotificationAdded(NotificationEntry entry) {
    }

    /**
     * Called when a new entry is created.
     */
+12 −3
Original line number Diff line number Diff line
@@ -262,9 +262,6 @@ public class NotificationEntryManager implements
                    listener.onEntryInflated(entry, inflatedFlags);
                }
                mNotificationData.add(entry);
                for (NotificationEntryListener listener : mNotificationEntryListeners) {
                    listener.onBeforeNotificationAdded(entry);
                }
                updateNotifications("onAsyncInflationFinished");
                for (NotificationEntryListener listener : mNotificationEntryListeners) {
                    listener.onNotificationAdded(entry);
@@ -563,6 +560,18 @@ public class NotificationEntryManager implements
        return mPendingNotifications.values();
    }

    /**
     * Gets the pending or visible notification entry with the given key. Returns null if
     * notification doesn't exist.
     */
    public NotificationEntry getPendingOrCurrentNotif(String key) {
        if (mPendingNotifications.containsKey(key)) {
            return mPendingNotifications.get(key);
        } else {
            return mNotificationData.get(key);
        }
    }

    private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) {
        NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry);
        if (activeExtender != null && activeExtender != extender) {
+0 −34
Original line number Diff line number Diff line
@@ -18,10 +18,6 @@ package com.android.systemui.statusbar.notification;

import static com.android.internal.util.Preconditions.checkNotNull;

import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;

import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -70,11 +66,6 @@ public class NotificationListController {
                boolean removedByUser) {
            mListContainer.cleanUpViewStateForEntry(entry);
        }

        @Override
        public void onBeforeNotificationAdded(NotificationEntry entry) {
            tagForeground(entry.getSbn());
        }
    };

    private final DeviceProvisionedListener mDeviceProvisionedListener =
@@ -84,29 +75,4 @@ public class NotificationListController {
                    mEntryManager.updateNotifications("device provisioned changed");
                }
            };

    // TODO: This method is horrifically inefficient
    private void tagForeground(StatusBarNotification notification) {
        ArraySet<Integer> activeOps =
                mForegroundServiceController.getAppOps(
                        notification.getUserId(), notification.getPackageName());
        if (activeOps != null) {
            int len = activeOps.size();
            for (int i = 0; i < len; i++) {
                updateNotificationsForAppOp(activeOps.valueAt(i), notification.getUid(),
                        notification.getPackageName(), true);
            }
        }
    }

    /** When an app op changes, propagate that change to notifications. */
    public void updateNotificationsForAppOp(int appOp, int uid, String pkg, boolean showIcon) {
        String foregroundKey =
                mForegroundServiceController.getStandardLayoutKey(UserHandle.getUserId(uid), pkg);
        if (foregroundKey != null) {
            mEntryManager
                    .getNotificationData().updateAppOp(appOp, uid, pkg, foregroundKey, showIcon);
            mEntryManager.updateNotifications("app opp changed pkg=" + pkg);
        }
    }
}
Loading