1 /* 2 * Copyright (c) 2015, Motorola Mobility LLC 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * - Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * - Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * - Neither the name of Motorola Mobility nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 26 * DAMAGE. 27 */ 28 29 package com.android.service.ims.presence; 30 31 import android.content.Context; 32 33 import com.android.ims.internal.Logger; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 public class PollingsQueue { 39 private Logger logger = Logger.getLogger(this.getClass().getName()); 40 41 private Context mContext; 42 private CapabilityPolling mCapabilityPolling; 43 private List<PollingTask> mPollingTasks = new ArrayList<PollingTask>(); 44 private boolean mAskVerifyResult = false; 45 private int mVerifyCounts = 0; 46 47 private static PollingsQueue sInstance = null; getInstance(Context context)48 public static synchronized PollingsQueue getInstance(Context context) { 49 if ((sInstance == null) && (context != null)) { 50 sInstance = new PollingsQueue(context); 51 } 52 53 return sInstance; 54 } 55 PollingsQueue(Context context)56 private PollingsQueue(Context context) { 57 mContext = context; 58 mPollingTasks.clear(); 59 } 60 setCapabilityPolling(CapabilityPolling cp)61 public synchronized void setCapabilityPolling(CapabilityPolling cp) { 62 mCapabilityPolling = cp; 63 } 64 getCapabilityPolling()65 public CapabilityPolling getCapabilityPolling() { 66 return mCapabilityPolling; 67 } 68 getContext()69 public Context getContext() { 70 return mContext; 71 } 72 clear()73 public synchronized void clear() { 74 mPollingTasks.clear(); 75 } 76 add(int type, List<Contacts.Item> list)77 public synchronized void add(int type, List<Contacts.Item> list) { 78 if (list.size() <= 0) { 79 return; 80 } 81 82 List<Contacts.Item> contacts = new ArrayList<Contacts.Item>(); 83 contacts.clear(); 84 for(int i = 0; i < list.size(); i++) { 85 Contacts.Item item = list.get(i); 86 87 boolean bExist = false; 88 for(int j = 0; j < contacts.size(); j++) { 89 Contacts.Item item0 = contacts.get(j); 90 if (item.equals(item0)) { 91 bExist = true; 92 break; 93 } 94 } 95 96 for (int j = 0; j < mPollingTasks.size(); j++) { 97 if (bExist) { 98 break; 99 } 100 PollingTask task = mPollingTasks.get(j); 101 for(int k = 0; k < task.mContacts.size(); k++) { 102 Contacts.Item item0 = task.mContacts.get(k); 103 if (item.equals(item0)) { 104 bExist = true; 105 break; 106 } 107 } 108 } 109 if (bExist) { 110 continue; 111 } 112 113 contacts.add(item); 114 if (type == CapabilityPolling.ACTION_POLLING_NORMAL) { 115 if (item.lastUpdateTime() == 0) { 116 type = CapabilityPolling.ACTION_POLLING_NEW_CONTACTS; 117 } 118 } 119 } 120 121 PollingTask taskCancelled = null; 122 int nTasks = mPollingTasks.size(); 123 logger.print("Before add(), the existing tasks number: " + nTasks); 124 125 if (contacts.size() <= 0) { 126 logger.debug("Empty/duplicated list, no request added."); 127 return; 128 } 129 130 int maxEntriesInRequest = PresenceSetting.getMaxNumberOfEntriesInRequestContainedList(); 131 logger.print("getMaxNumberOfEntriesInRequestContainedList: " + maxEntriesInRequest); 132 if (maxEntriesInRequest == -1) { 133 maxEntriesInRequest = 100; 134 } 135 136 int noOfIterations = contacts.size() / maxEntriesInRequest; 137 for (int loop = 0; loop <= noOfIterations; loop++) { 138 int entriesInRequest = maxEntriesInRequest; 139 if (loop == noOfIterations) { 140 entriesInRequest = contacts.size() % maxEntriesInRequest; 141 } 142 143 List<Contacts.Item> cl = new ArrayList<Contacts.Item>(); 144 cl.clear(); 145 int pos = loop * maxEntriesInRequest; 146 for (int i = 0; i < entriesInRequest; i++) { 147 Contacts.Item item = contacts.get(pos); 148 cl.add(item); 149 pos++; 150 } 151 152 if (cl.size() > 0) { 153 PollingTask task = new PollingTask(type, cl); 154 logger.debug("One new polling task added: " + task); 155 156 boolean bInserted = false; 157 for (int i = 0; i < mPollingTasks.size(); i++) { 158 PollingTask task0 = mPollingTasks.get(i); 159 if (task.mType > task0.mType) { 160 bInserted = true; 161 mPollingTasks.add(i, task); 162 if ((i == 0) && (taskCancelled == null)) { 163 taskCancelled = task0; 164 } 165 break; 166 } 167 } 168 if (!bInserted) { 169 mPollingTasks.add(task); 170 } 171 } 172 } 173 174 logger.print("After add(), the total tasks number: " + mPollingTasks.size()); 175 if (nTasks <= 0) { 176 if (mPollingTasks.size() > 0) { 177 PollingTask task = mPollingTasks.get(0); 178 task.execute(); 179 } 180 } else { 181 if (taskCancelled != null) { 182 taskCancelled.cancel(); 183 } 184 } 185 } 186 remove(PollingTask task)187 public synchronized void remove(PollingTask task) { 188 int nTasks = mPollingTasks.size(); 189 if (nTasks <= 0) { 190 return; 191 } 192 193 logger.debug("Remove polling task: " + task); 194 if (task != null) { 195 for (int i = 0; i < nTasks; i++) { 196 PollingTask task0 = mPollingTasks.get(i); 197 if (task0.equals(task)) { 198 if (task.isCompleted()) { 199 mVerifyCounts = 0; 200 } else { 201 mAskVerifyResult = true; 202 } 203 mPollingTasks.remove(i); 204 break; 205 } 206 } 207 } 208 209 if (mPollingTasks.size() > 0) { 210 PollingTask task0 = mPollingTasks.get(0); 211 task0.execute(); 212 } else { 213 if (mAskVerifyResult) { 214 mAskVerifyResult = false; 215 mVerifyCounts++; 216 if (mCapabilityPolling != null) { 217 mCapabilityPolling.enqueueVerifyPollingResult(mVerifyCounts); 218 } 219 } 220 } 221 } 222 retry(long id)223 public synchronized void retry(long id) { 224 int nTasks = mPollingTasks.size(); 225 if (nTasks <= 0) { 226 return; 227 } 228 229 PollingTask task0 = null; 230 for (int i = 0; i < nTasks; i++) { 231 PollingTask task = mPollingTasks.get(i); 232 if (task.mId == id) { 233 task0 = task; 234 break; 235 } 236 } 237 238 if (task0 == null) { 239 logger.debug("Trigger wrong retry: " + id); 240 task0 = mPollingTasks.get(0); 241 } 242 243 task0.execute(); 244 } 245 } 246 247