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, int associatedSub)77 public synchronized void add(int type, List<Contacts.Item> list, int associatedSub) { 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 = 131 PresenceSetting.getMaxNumberOfEntriesInRequestContainedList(associatedSub); 132 logger.print("getMaxNumberOfEntriesInRequestContainedList: " + maxEntriesInRequest); 133 if (maxEntriesInRequest == -1) { 134 maxEntriesInRequest = 100; 135 } 136 137 int noOfIterations = contacts.size() / maxEntriesInRequest; 138 for (int loop = 0; loop <= noOfIterations; loop++) { 139 int entriesInRequest = maxEntriesInRequest; 140 if (loop == noOfIterations) { 141 entriesInRequest = contacts.size() % maxEntriesInRequest; 142 } 143 144 List<Contacts.Item> cl = new ArrayList<Contacts.Item>(); 145 cl.clear(); 146 int pos = loop * maxEntriesInRequest; 147 for (int i = 0; i < entriesInRequest; i++) { 148 Contacts.Item item = contacts.get(pos); 149 cl.add(item); 150 pos++; 151 } 152 153 if (cl.size() > 0) { 154 PollingTask task = new PollingTask(type, cl, associatedSub); 155 logger.debug("One new polling task added: " + task); 156 157 boolean bInserted = false; 158 for (int i = 0; i < mPollingTasks.size(); i++) { 159 PollingTask task0 = mPollingTasks.get(i); 160 if (task.mType > task0.mType) { 161 bInserted = true; 162 mPollingTasks.add(i, task); 163 if ((i == 0) && (taskCancelled == null)) { 164 taskCancelled = task0; 165 } 166 break; 167 } 168 } 169 if (!bInserted) { 170 mPollingTasks.add(task); 171 } 172 } 173 } 174 175 logger.print("After add(), the total tasks number: " + mPollingTasks.size()); 176 if (nTasks <= 0) { 177 if (mPollingTasks.size() > 0) { 178 PollingTask task = mPollingTasks.get(0); 179 task.execute(); 180 } 181 } else { 182 if (taskCancelled != null) { 183 taskCancelled.cancel(); 184 } 185 } 186 } 187 remove(PollingTask task)188 public synchronized void remove(PollingTask task) { 189 int nTasks = mPollingTasks.size(); 190 if (nTasks <= 0) { 191 return; 192 } 193 194 logger.debug("Remove polling task: " + task); 195 if (task != null) { 196 for (int i = 0; i < nTasks; i++) { 197 PollingTask task0 = mPollingTasks.get(i); 198 if (task0.equals(task)) { 199 if (task.isCompleted()) { 200 mVerifyCounts = 0; 201 } else { 202 mAskVerifyResult = true; 203 } 204 mPollingTasks.remove(i); 205 break; 206 } 207 } 208 } 209 210 if (mPollingTasks.size() > 0) { 211 PollingTask task0 = mPollingTasks.get(0); 212 task0.execute(); 213 } else { 214 if (mAskVerifyResult) { 215 mAskVerifyResult = false; 216 mVerifyCounts++; 217 if (mCapabilityPolling != null) { 218 mCapabilityPolling.enqueueVerifyPollingResult(mVerifyCounts); 219 } 220 } 221 } 222 } 223 retry(long id)224 public synchronized void retry(long id) { 225 int nTasks = mPollingTasks.size(); 226 if (nTasks <= 0) { 227 return; 228 } 229 230 PollingTask task0 = null; 231 for (int i = 0; i < nTasks; i++) { 232 PollingTask task = mPollingTasks.get(i); 233 if (task.mId == id) { 234 task0 = task; 235 break; 236 } 237 } 238 239 if (task0 == null) { 240 logger.debug("Trigger wrong retry: " + id); 241 task0 = mPollingTasks.get(0); 242 } 243 244 task0.execute(); 245 } 246 } 247 248