1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar; 18 19 import android.service.notification.StatusBarNotification; 20 import android.os.IBinder; 21 import android.view.View; 22 import android.widget.ImageView; 23 24 import com.android.systemui.R; 25 26 import java.util.Comparator; 27 import java.util.ArrayList; 28 29 /** 30 * The list of currently displaying notifications. 31 */ 32 public class NotificationData { 33 public static final class Entry { 34 public IBinder key; 35 public StatusBarNotification notification; 36 public StatusBarIconView icon; 37 public View row; // the outer expanded view 38 public View content; // takes the click events and sends the PendingIntent 39 public View expanded; // the inflated RemoteViews 40 public ImageView largeIcon; 41 protected View expandedLarge; 42 public Entry() {} 43 public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) { 44 this.key = key; 45 this.notification = n; 46 this.icon = ic; 47 } 48 public void setLargeView(View expandedLarge) { 49 this.expandedLarge = expandedLarge; 50 writeBooleanTag(row, R.id.expandable_tag, expandedLarge != null); 51 } 52 public View getLargeView() { 53 return expandedLarge; 54 } 55 /** 56 * Return whether the entry can be expanded. 57 */ 58 public boolean expandable() { 59 return NotificationData.getIsExpandable(row); 60 } 61 /** 62 * Return whether the entry has been manually expanded by the user. 63 */ 64 public boolean userExpanded() { 65 return NotificationData.getUserExpanded(row); 66 } 67 /** 68 * Set the flag indicating that this was manually expanded by the user. 69 */ 70 public boolean setUserExpanded(boolean userExpanded) { 71 return NotificationData.setUserExpanded(row, userExpanded); 72 } 73 /** 74 * Return whether the entry is being touched by the user. 75 */ 76 public boolean userLocked() { 77 return NotificationData.getUserLocked(row); 78 } 79 /** 80 * Set the flag indicating that this is being touched by the user. 81 */ 82 public boolean setUserLocked(boolean userLocked) { 83 return NotificationData.setUserLocked(row, userLocked); 84 } 85 } 86 private final ArrayList<Entry> mEntries = new ArrayList<Entry>(); 87 private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() { 88 // sort first by score, then by when 89 public int compare(Entry a, Entry b) { 90 final StatusBarNotification na = a.notification; 91 final StatusBarNotification nb = b.notification; 92 int d = na.getScore() - nb.getScore(); 93 return (d != 0) 94 ? d 95 : (int)(na.getNotification().when - nb.getNotification().when); 96 } 97 }; 98 99 public int size() { 100 return mEntries.size(); 101 } 102 103 public Entry get(int i) { 104 return mEntries.get(i); 105 } 106 107 public Entry findByKey(IBinder key) { 108 for (Entry e : mEntries) { 109 if (e.key == key) { 110 return e; 111 } 112 } 113 return null; 114 } 115 116 public int add(Entry entry) { 117 int i; 118 int N = mEntries.size(); 119 for (i=0; i<N; i++) { 120 if (mEntryCmp.compare(mEntries.get(i), entry) > 0) { 121 break; 122 } 123 } 124 mEntries.add(i, entry); 125 return i; 126 } 127 128 public int add(IBinder key, StatusBarNotification notification, View row, View content, 129 View expanded, StatusBarIconView icon) { 130 Entry entry = new Entry(); 131 entry.key = key; 132 entry.notification = notification; 133 entry.row = row; 134 entry.content = content; 135 entry.expanded = expanded; 136 entry.icon = icon; 137 entry.largeIcon = null; // TODO add support for large icons 138 return add(entry); 139 } 140 141 public Entry remove(IBinder key) { 142 Entry e = findByKey(key); 143 if (e != null) { 144 mEntries.remove(e); 145 } 146 return e; 147 } 148 149 /** 150 * Return whether there are any visible items (i.e. items without an error). 151 */ 152 public boolean hasVisibleItems() { 153 for (Entry e : mEntries) { 154 if (e.expanded != null) { // the view successfully inflated 155 return true; 156 } 157 } 158 return false; 159 } 160 161 /** 162 * Return whether there are any clearable items (that aren't errors). 163 */ 164 public boolean hasClearableItems() { 165 for (Entry e : mEntries) { 166 if (e.expanded != null) { // the view successfully inflated 167 if (e.notification.isClearable()) { 168 return true; 169 } 170 } 171 } 172 return false; 173 } 174 175 protected static boolean readBooleanTag(View view, int id) { 176 if (view != null) { 177 Object value = view.getTag(id); 178 return value != null && value instanceof Boolean && ((Boolean) value).booleanValue(); 179 } 180 return false; 181 } 182 183 protected static boolean writeBooleanTag(View view, int id, boolean value) { 184 if (view != null) { 185 view.setTag(id, Boolean.valueOf(value)); 186 return value; 187 } 188 return false; 189 } 190 191 /** 192 * Return whether the entry can be expanded. 193 */ 194 public static boolean getIsExpandable(View row) { 195 return readBooleanTag(row, R.id.expandable_tag); 196 } 197 198 /** 199 * Return whether the entry has been manually expanded by the user. 200 */ 201 public static boolean getUserExpanded(View row) { 202 return readBooleanTag(row, R.id.user_expanded_tag); 203 } 204 205 /** 206 * Set whether the entry has been manually expanded by the user. 207 */ 208 public static boolean setUserExpanded(View row, boolean userExpanded) { 209 return writeBooleanTag(row, R.id.user_expanded_tag, userExpanded); 210 } 211 212 /** 213 * Return whether the entry is being touched by the user. 214 */ 215 public static boolean getUserLocked(View row) { 216 return readBooleanTag(row, R.id.user_lock_tag); 217 } 218 219 /** 220 * Set whether the entry is being touched by the user. 221 */ 222 public static boolean setUserLocked(View row, boolean userLocked) { 223 return writeBooleanTag(row, R.id.user_lock_tag, userLocked); 224 } 225 } 226