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

Commit f025404a authored by Daniel Sandler's avatar Daniel Sandler Committed by Android (Google) Code Review
Browse files

Merge "New INotificationListener interface."

parents 1b15ba5d 09a247e9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ LOCAL_SRC_FILES += \
	core/java/android/app/IAlarmManager.aidl \
	core/java/android/app/IBackupAgent.aidl \
	core/java/android/app/IInstrumentationWatcher.aidl \
	core/java/android/app/INotificationListener.aidl \
	core/java/android/app/INotificationManager.aidl \
	core/java/android/app/IProcessObserver.aidl \
	core/java/android/app/ISearchManager.aidl \
+26 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2013, 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 android.app;

import com.android.internal.statusbar.StatusBarNotification;

/** @hide */
oneway interface INotificationListener
{
    void onNotificationPosted(in StatusBarNotification notification);
    void onNotificationRemoved(in StatusBarNotification notification);
}
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

package android.app;

import android.app.INotificationListener;
import android.app.ITransientNotification;
import android.app.Notification;
import android.content.Intent;
@@ -39,5 +40,8 @@ interface INotificationManager

    StatusBarNotification[] getActiveNotifications(String callingPkg);
    StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);

    void registerListener(in INotificationListener listener, int userid);
    void unregisterListener(in INotificationListener listener, int userid);
}
+0 −0

Empty file added.

+91 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.INotificationListener;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.PendingIntent;
@@ -151,6 +152,7 @@ public class NotificationManagerService extends INotificationManager.Stub
    private boolean mInCall = false;
    private boolean mNotificationPulseEnabled;

    // used as a mutex for access to all active notifications & listeners
    private final ArrayList<NotificationRecord> mNotificationList =
            new ArrayList<NotificationRecord>();

@@ -161,6 +163,8 @@ public class NotificationManagerService extends INotificationManager.Stub

    private final AppOpsManager mAppOps;

    private ArrayList<NotificationListenerInfo> mListeners = new ArrayList<NotificationListenerInfo>();

    // Notification control database. For now just contains disabled packages.
    private AtomicFile mPolicyFile;
    private HashSet<String> mBlockedPackages = new HashSet<String>();
@@ -174,6 +178,38 @@ public class NotificationManagerService extends INotificationManager.Stub
    private static final String TAG_PACKAGE = "package";
    private static final String ATTR_NAME = "name";

    private class NotificationListenerInfo implements DeathRecipient {
        INotificationListener listener;
        int userid;
        public NotificationListenerInfo(INotificationListener listener, int userid) {
            this.listener = listener;
            this.userid = userid;
        }

        public void notifyPostedIfUserMatch(StatusBarNotification sbn) {
            if (this.userid != sbn.getUserId()) return;
            try {
                listener.onNotificationPosted(sbn);
            } catch (RemoteException ex) {
                // not there?
            }
        }

        public void notifyRemovedIfUserMatch(StatusBarNotification sbn) {
            if (this.userid != sbn.getUserId()) return;
            try {
                listener.onNotificationRemoved(sbn);
            } catch (RemoteException ex) {
                // not there?
            }
        }

        @Override
        public void binderDied() {
            unregisterListener(this.listener, this.userid);
        }
    }

    private static class Archive {
        static final int BUFFER_SIZE = 1000;
        ArrayDeque<StatusBarNotification> mBuffer = new ArrayDeque<StatusBarNotification>(BUFFER_SIZE);
@@ -406,6 +442,56 @@ public class NotificationManagerService extends INotificationManager.Stub
        return tmp;
    }

    @Override
    public void registerListener(final INotificationListener listener, final int userid) {
        checkCallerIsSystem();
        synchronized (mNotificationList) {
            try {
                NotificationListenerInfo info = new NotificationListenerInfo(listener, userid);
                listener.asBinder().linkToDeath(info, 0);
                mListeners.add(info);
            } catch (RemoteException e) {
                // already dead
            }
        }
    }

    @Override
    public void unregisterListener(INotificationListener listener, int userid) {
        checkCallerIsSystem();
        synchronized (mNotificationList) {
            final int N = mListeners.size();
            for (int i=N-1; i>=0; i--) {
                final NotificationListenerInfo info = mListeners.get(i);
                if (info.listener == listener && info.userid == userid) {
                    mListeners.remove(listener);
                }
            }
        }
    }

    private void notifyPostedLocked(NotificationRecord n) {
        final StatusBarNotification sbn = n.sbn;
        for (final NotificationListenerInfo info : mListeners) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    info.notifyPostedIfUserMatch(sbn);
                }});
        }
    }

    private void notifyRemovedLocked(NotificationRecord n) {
        final StatusBarNotification sbn = n.sbn;
        for (final NotificationListenerInfo info : mListeners) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    info.notifyRemovedIfUserMatch(sbn);
                }});
        }
    }

    public static final class NotificationRecord
    {
        final StatusBarNotification sbn;
@@ -1165,6 +1251,8 @@ public class NotificationManagerService extends INotificationManager.Stub

                // finally, keep some of this information around for later use
                mArchive.record(n);

                notifyPostedLocked(r);
            } else {
                Slog.e(TAG, "Ignoring notification with icon==0: " + notification);
                if (old != null && old.statusBarKey != null) {
@@ -1175,6 +1263,8 @@ public class NotificationManagerService extends INotificationManager.Stub
                    finally {
                        Binder.restoreCallingIdentity(identity);
                    }

                    notifyRemovedLocked(r);
                }
                return; // do not play sounds, show lights, etc. for invalid notifications
            }
@@ -1341,6 +1431,7 @@ public class NotificationManagerService extends INotificationManager.Stub
                Binder.restoreCallingIdentity(identity);
            }
            r.statusBarKey = null;
            notifyRemovedLocked(r);
        }

        // sound