1503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato/*
2503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * Copyright (C) 2008 The Android Open Source Project
3503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato *
4503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * you may not use this file except in compliance with the License.
6503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * You may obtain a copy of the License at
7503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato *
8503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato *
10503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * Unless required by applicable law or agreed to in writing, software
11503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * See the License for the specific language governing permissions and
14503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato * limitations under the License.
15503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato */
16503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato
1779de0c550037a5328bbc7f4fddaf02f192a5c283Joe Onoratopackage com.android.systemui.statusbar;
18503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato
1920da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onoratoimport android.app.Notification;
20e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onoratoimport android.os.IBinder;
21e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onoratoimport android.view.View;
2280a44401a22344f7eabce6976372ab144ef22893Joe Onoratoimport android.widget.ImageView;
23503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato
24e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
258fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wrenimport com.android.systemui.R;
26e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato
27379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandlerimport java.util.Comparator;
28e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onoratoimport java.util.ArrayList;
29e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato
30e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato/**
31e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato * The list of currently displaying notifications.
32e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato */
33503007dd023668b1e45de948d3673e594d7f5a82Joe Onoratopublic class NotificationData {
34e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    public static final class Entry {
35e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        public IBinder key;
36e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        public StatusBarNotification notification;
3766b4c5bb36f57a9d83bb7f34288235b82f9be407Joe Onorato        public StatusBarIconView icon;
389c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        public View row; // the outer expanded view
399c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        public View content; // takes the click events and sends the PendingIntent
409c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        public View expanded; // the inflated RemoteViews
4180a44401a22344f7eabce6976372ab144ef22893Joe Onorato        public ImageView largeIcon;
428fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        protected View expandedLarge;
433eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public Entry() {}
443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) {
453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            this.key = key;
463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            this.notification = n;
473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            this.icon = ic;
483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
498fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        public void setLargeView(View expandedLarge) {
508fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            this.expandedLarge = expandedLarge;
518fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            writeBooleanTag(row, R.id.expandable_tag, expandedLarge != null);
528fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
538fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        public View getLargeView() {
548fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            return expandedLarge;
558fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
568fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        /**
578fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren         * Return whether the entry can be expanded.
588fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren         */
598fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        public boolean expandable() {
608fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            return NotificationData.getIsExpandable(row);
618fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
628fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        /**
638fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren         * Return whether the entry has been manually expanded by the user.
648fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren         */
658fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        public boolean userExpanded() {
668fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            return NotificationData.getUserExpanded(row);
678fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
685ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren        /**
695ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren         * Set the flag indicating that this was manually expanded by the user.
705ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren         */
715ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren        public boolean setUserExpanded(boolean userExpanded) {
725ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren            return NotificationData.setUserExpanded(row, userExpanded);
735ae1ea8400d576b90f0ef02b2f10201d74729be6Chris Wren        }
743ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        /**
753ddab0dcc1039137f05a28ff86477601a223a0faChris Wren         * Return whether the entry is being touched by the user.
763ddab0dcc1039137f05a28ff86477601a223a0faChris Wren         */
773ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        public boolean userLocked() {
783ddab0dcc1039137f05a28ff86477601a223a0faChris Wren            return NotificationData.getUserLocked(row);
793ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        }
803ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        /**
813ddab0dcc1039137f05a28ff86477601a223a0faChris Wren         * Set the flag indicating that this is being touched by the user.
823ddab0dcc1039137f05a28ff86477601a223a0faChris Wren         */
833ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        public boolean setUserLocked(boolean userLocked) {
843ddab0dcc1039137f05a28ff86477601a223a0faChris Wren            return NotificationData.setUserLocked(row, userLocked);
853ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        }
86e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    }
87e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
88379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() {
892561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        // sort first by score, then by when
90379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        public int compare(Entry a, Entry b) {
91a31e4190cb44eaa51bb8dee7d715fcd72d6c0b03Daniel Sandler            final StatusBarNotification na = a.notification;
92a31e4190cb44eaa51bb8dee7d715fcd72d6c0b03Daniel Sandler            final StatusBarNotification nb = b.notification;
932561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            int d = na.score - nb.score;
942561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            return (d != 0)
952561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                ? d
96a31e4190cb44eaa51bb8dee7d715fcd72d6c0b03Daniel Sandler                : (int)(na.notification.when - nb.notification.when);
97379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        }
98379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    };
99e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato
100e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    public int size() {
101e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        return mEntries.size();
102e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    }
103e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato
1040f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    public Entry get(int i) {
1050f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        return mEntries.get(i);
1060f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    }
1070f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
108379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    public Entry findByKey(IBinder key) {
109379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        for (Entry e : mEntries) {
110379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            if (e.key == key) {
111379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler                return e;
1120e26dffd6cfcb09b08a94a857b891fdef7fe2b1eJoe Onorato            }
1130e26dffd6cfcb09b08a94a857b891fdef7fe2b1eJoe Onorato        }
114379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        return null;
1150e26dffd6cfcb09b08a94a857b891fdef7fe2b1eJoe Onorato    }
1160e26dffd6cfcb09b08a94a857b891fdef7fe2b1eJoe Onorato
1173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    public int add(Entry entry) {
118379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        int i;
119379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        int N = mEntries.size();
120379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        for (i=0; i<N; i++) {
121379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            if (mEntryCmp.compare(mEntries.get(i), entry) > 0) {
122379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler                break;
123379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            }
124379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        }
125379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        mEntries.add(i, entry);
126379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        return i;
1273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
1283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1299c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato    public int add(IBinder key, StatusBarNotification notification, View row, View content,
1309c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato            View expanded, StatusBarIconView icon) {
131e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        Entry entry = new Entry();
132e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        entry.key = key;
133e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        entry.notification = notification;
1349c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        entry.row = row;
1359c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        entry.content = content;
136e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        entry.expanded = expanded;
13766b4c5bb36f57a9d83bb7f34288235b82f9be407Joe Onorato        entry.icon = icon;
13880a44401a22344f7eabce6976372ab144ef22893Joe Onorato        entry.largeIcon = null; // TODO add support for large icons
1393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return add(entry);
140e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato    }
141e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato
14266b4c5bb36f57a9d83bb7f34288235b82f9be407Joe Onorato    public Entry remove(IBinder key) {
143379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        Entry e = findByKey(key);
144379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (e != null) {
145379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            mEntries.remove(e);
146e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato        }
147379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        return e;
148503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato    }
14920da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato
15020da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    /**
15120da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato     * Return whether there are any visible items (i.e. items without an error).
15220da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato     */
15320da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    public boolean hasVisibleItems() {
154379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        for (Entry e : mEntries) {
155379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            if (e.expanded != null) { // the view successfully inflated
1569c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato                return true;
1579c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato            }
1589c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        }
1599c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato        return false;
16020da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    }
16120da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato
16220da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    /**
16320da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato     * Return whether there are any clearable items (that aren't errors).
16420da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato     */
16520da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    public boolean hasClearableItems() {
166379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        for (Entry e : mEntries) {
167379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            if (e.expanded != null) { // the view successfully inflated
1685dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato                if (e.notification.isClearable()) {
1699c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato                    return true;
1709c1d823465fa0bd782b2ea4afc518835b4bfecceJoe Onorato                }
17120da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato            }
17220da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato        }
17320da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato        return false;
17420da8f8ac9cfc8b845231c6b93f5b64a764ab39aJoe Onorato    }
1758fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren
1768fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    protected static boolean readBooleanTag(View view, int id)  {
1778fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        if (view != null) {
1788fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            Object value = view.getTag(id);
1798fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            return value != null && value instanceof Boolean && ((Boolean) value).booleanValue();
1808fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
1818fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        return false;
1828fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    }
1838fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren
1848fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    protected static boolean writeBooleanTag(View view, int id, boolean value)  {
1858fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        if (view != null) {
1868fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            view.setTag(id, Boolean.valueOf(value));
1878fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren            return value;
1888fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        }
1898fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        return false;
1908fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    }
1918fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren
1928fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    /**
1938fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     * Return whether the entry can be expanded.
1948fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     */
1958fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    public static boolean getIsExpandable(View row) {
1968fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        return readBooleanTag(row, R.id.expandable_tag);
1978fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    }
1988fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren
1998fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    /**
2008fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     * Return whether the entry has been manually expanded by the user.
2018fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     */
2028fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    public static boolean getUserExpanded(View row) {
2038fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        return readBooleanTag(row, R.id.user_expanded_tag);
2048fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    }
2058fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren
2068fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    /**
2078fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     * Set whether the entry has been manually expanded by the user.
2088fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren     */
2098fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    public static boolean setUserExpanded(View row, boolean userExpanded) {
2108fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren        return writeBooleanTag(row, R.id.user_expanded_tag, userExpanded);
2118fd12657e353a4a6f6d875a0d86850426fec00e8Chris Wren    }
2123ddab0dcc1039137f05a28ff86477601a223a0faChris Wren
2133ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    /**
2143ddab0dcc1039137f05a28ff86477601a223a0faChris Wren     * Return whether the entry is being touched by the user.
2153ddab0dcc1039137f05a28ff86477601a223a0faChris Wren     */
2163ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    public static boolean getUserLocked(View row) {
2173ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        return readBooleanTag(row, R.id.user_lock_tag);
2183ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    }
2193ddab0dcc1039137f05a28ff86477601a223a0faChris Wren
2203ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    /**
2213ddab0dcc1039137f05a28ff86477601a223a0faChris Wren     * Set whether the entry is being touched by the user.
2223ddab0dcc1039137f05a28ff86477601a223a0faChris Wren     */
2233ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    public static boolean setUserLocked(View row, boolean userLocked) {
2243ddab0dcc1039137f05a28ff86477601a223a0faChris Wren        return writeBooleanTag(row, R.id.user_lock_tag, userLocked);
2253ddab0dcc1039137f05a28ff86477601a223a0faChris Wren    }
226503007dd023668b1e45de948d3673e594d7f5a82Joe Onorato}
227