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