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

Commit 05ac6544 authored by Jason Monk's avatar Jason Monk Committed by android-build-merger
Browse files

Merge "Add notification listener plugin hook" into oc-dr1-dev

am: 8f8b5ac0

Change-Id: Id40b6acf8e144c92ea4cb9a3604bc798d3c51e8b
parents 425a9587 8f8b5ac0
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.plugins;

import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;

import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;

@ProvidesInterface(action = NotificationListenerController.ACTION,
        version = NotificationListenerController.VERSION)
@DependsOn(target = NotificationProvider.class)
public interface NotificationListenerController extends Plugin {
    String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_ASSISTANT";
    int VERSION = 1;

    void onListenerConnected(NotificationProvider provider);

    default boolean onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
        return false;
    }
    default boolean onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
        return false;
    }

    default StatusBarNotification[] getActiveNotifications(
            StatusBarNotification[] activeNotifications) {
        return activeNotifications;
    }

    default RankingMap getCurrentRanking(RankingMap currentRanking) {
        return currentRanking;
    }

    @ProvidesInterface(version = NotificationProvider.VERSION)
    interface NotificationProvider {
        int VERSION = 1;

        // Methods to get info about current notifications
        StatusBarNotification[] getActiveNotifications();
        RankingMap getRankingMap();

        // Methods to notify sysui of changes to notification list.
        void addNotification(StatusBarNotification sbn);
        void removeNotification(StatusBarNotification sbn);
        void updateRanking();
    }
}
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.phone;

import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;

import com.android.systemui.Dependency;
import com.android.systemui.plugins.NotificationListenerController;
import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;

import java.util.ArrayList;

/**
 * A version of NotificationListenerService that passes all info to
 * any plugins connected. Also allows those plugins the chance to cancel
 * any incoming callbacks or to trigger new ones.
 */
public class NotificationListenerWithPlugins extends NotificationListenerService implements
        PluginListener<NotificationListenerController> {

    private ArrayList<NotificationListenerController> mPlugins = new ArrayList<>();
    private boolean mConnected;

    @Override
    public void registerAsSystemService(Context context, ComponentName componentName,
            int currentUser) throws RemoteException {
        super.registerAsSystemService(context, componentName, currentUser);
        Dependency.get(PluginManager.class).addPluginListener(this,
                NotificationListenerController.class);
    }

    @Override
    public void unregisterAsSystemService() throws RemoteException {
        super.unregisterAsSystemService();
        Dependency.get(PluginManager.class).removePluginListener(this);
    }

    @Override
    public StatusBarNotification[] getActiveNotifications() {
        StatusBarNotification[] activeNotifications = super.getActiveNotifications();
        for (NotificationListenerController plugin : mPlugins) {
            activeNotifications = plugin.getActiveNotifications(activeNotifications);
        }
        return activeNotifications;
    }

    @Override
    public RankingMap getCurrentRanking() {
        RankingMap currentRanking = super.getCurrentRanking();
        for (NotificationListenerController plugin : mPlugins) {
            currentRanking = plugin.getCurrentRanking(currentRanking);
        }
        return currentRanking;
    }

    public void onPluginConnected() {
        mConnected = true;
        mPlugins.forEach(p -> p.onListenerConnected(getProvider()));
    }

    /**
     * Called when listener receives a onNotificationPosted.
     * Returns true to indicate this callback should be skipped.
     */
    public boolean onPluginNotificationPosted(StatusBarNotification sbn,
            final RankingMap rankingMap) {
        for (NotificationListenerController plugin : mPlugins) {
            if (plugin.onNotificationPosted(sbn, rankingMap)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Called when listener receives a onNotificationRemoved.
     * Returns true to indicate this callback should be skipped.
     */
    public boolean onPluginNotificationRemoved(StatusBarNotification sbn,
            final RankingMap rankingMap) {
        for (NotificationListenerController plugin : mPlugins) {
            if (plugin.onNotificationRemoved(sbn, rankingMap)) {
                return true;
            }
        }
        return false;
    }

    public RankingMap onPluginRankingUpdate(RankingMap rankingMap) {
        return getCurrentRanking();
    }

    @Override
    public void onPluginConnected(NotificationListenerController plugin, Context pluginContext) {
        mPlugins.add(plugin);
        if (mConnected) {
            plugin.onListenerConnected(getProvider());
        }
    }

    @Override
    public void onPluginDisconnected(NotificationListenerController plugin) {
        mPlugins.remove(plugin);
    }

    private NotificationProvider getProvider() {
        return new NotificationProvider() {
            @Override
            public StatusBarNotification[] getActiveNotifications() {
                return NotificationListenerWithPlugins.super.getActiveNotifications();
            }

            @Override
            public RankingMap getRankingMap() {
                return NotificationListenerWithPlugins.super.getCurrentRanking();
            }

            @Override
            public void addNotification(StatusBarNotification sbn) {
                onNotificationPosted(sbn, getRankingMap());
            }

            @Override
            public void removeNotification(StatusBarNotification sbn) {
                onNotificationRemoved(sbn, getRankingMap());
            }

            @Override
            public void updateRanking() {
                onNotificationRankingUpdate(getRankingMap());
            }
        };
    }
}
+10 −17
Original line number Diff line number Diff line
@@ -5769,11 +5769,12 @@ public class StatusBar extends SystemUI implements DemoMode,
        }
    };

    private final NotificationListenerService mNotificationListener =
            new NotificationListenerService() {
    private final NotificationListenerWithPlugins mNotificationListener =
            new NotificationListenerWithPlugins() {
        @Override
        public void onListenerConnected() {
            if (DEBUG) Log.d(TAG, "onListenerConnected");
            onPluginConnected();
            final StatusBarNotification[] notifications = getActiveNotifications();
            if (notifications == null) {
                Log.w(TAG, "onListenerConnected unable to get active notifications.");
@@ -5798,7 +5799,7 @@ public class StatusBar extends SystemUI implements DemoMode,
        public void onNotificationPosted(final StatusBarNotification sbn,
                final RankingMap rankingMap) {
            if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
            if (sbn != null) {
            if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
@@ -5842,14 +5843,9 @@ public class StatusBar extends SystemUI implements DemoMode,
        public void onNotificationRemoved(StatusBarNotification sbn,
                final RankingMap rankingMap) {
            if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
            if (sbn != null) {
            if (sbn != null && !onPluginNotificationRemoved(sbn, rankingMap)) {
                final String key = sbn.getKey();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        removeNotification(key, rankingMap);
                    }
                });
                mHandler.post(() -> removeNotification(key, rankingMap));
            }
        }

@@ -5857,13 +5853,10 @@ public class StatusBar extends SystemUI implements DemoMode,
        public void onNotificationRankingUpdate(final RankingMap rankingMap) {
            if (DEBUG) Log.d(TAG, "onRankingUpdate");
            if (rankingMap != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateNotificationRanking(rankingMap);
                RankingMap r = onPluginRankingUpdate(rankingMap);
                mHandler.post(() -> updateNotificationRanking(r));
            }
        }
            });
        }                            }

    };