Kenny Root | 15a4d2f | 2010-03-11 18:20:12 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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 | |
Jeff Sharkey | 7a96c39 | 2012-11-15 14:01:46 -0800 | [diff] [blame] | 17 | package com.android.server.content; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 18 | |
| 19 | import android.accounts.Account; |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 20 | import android.content.pm.PackageManager; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 21 | import android.content.ComponentName; |
Jeff Sharkey | 7a96c39 | 2012-11-15 14:01:46 -0800 | [diff] [blame] | 22 | import android.content.ContentResolver; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 23 | import android.content.SyncRequest; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 24 | import android.os.Bundle; |
| 25 | import android.os.SystemClock; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 26 | import android.util.Pair; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 27 | |
| 28 | /** |
| 29 | * Value type that represents a sync operation. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 30 | * TODO: This is the class to flesh out with all the scheduling data - metered/unmetered, |
| 31 | * transfer-size, etc. |
| 32 | * {@hide} |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 33 | */ |
| 34 | public class SyncOperation implements Comparable { |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 35 | public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1; |
| 36 | public static final int REASON_ACCOUNTS_UPDATED = -2; |
| 37 | public static final int REASON_SERVICE_CHANGED = -3; |
| 38 | public static final int REASON_PERIODIC = -4; |
| 39 | public static final int REASON_IS_SYNCABLE = -5; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 40 | /** Sync started because it has just been set to sync automatically. */ |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 41 | public static final int REASON_SYNC_AUTO = -6; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 42 | /** Sync started because master sync automatically has been set to true. */ |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 43 | public static final int REASON_MASTER_SYNC_AUTO = -7; |
| 44 | public static final int REASON_USER_START = -8; |
| 45 | |
| 46 | private static String[] REASON_NAMES = new String[] { |
| 47 | "DataSettingsChanged", |
| 48 | "AccountsUpdated", |
| 49 | "ServiceChanged", |
| 50 | "Periodic", |
| 51 | "IsSyncable", |
| 52 | "AutoSync", |
| 53 | "MasterSyncAuto", |
| 54 | "UserStart", |
| 55 | }; |
| 56 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 57 | /** Account info to identify a SyncAdapter registered with the system. */ |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 58 | public final Account account; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 59 | /** Authority info to identify a SyncAdapter registered with the system. */ |
| 60 | public final String authority; |
| 61 | /** Service to which this operation will bind to perform the sync. */ |
| 62 | public final ComponentName service; |
Amith Yamasani | 04e0d26 | 2012-02-14 11:50:53 -0800 | [diff] [blame] | 63 | public final int userId; |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 64 | public final int reason; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 65 | public int syncSource; |
Fred Quintana | 0c4d04a | 2010-11-03 17:02:55 -0700 | [diff] [blame] | 66 | public final boolean allowParallelSyncs; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 67 | public Bundle extras; |
| 68 | public final String key; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 69 | public boolean expedited; |
| 70 | public SyncStorageEngine.PendingOperation pendingOperation; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 71 | /** Elapsed real time in millis at which to run this sync. */ |
| 72 | public long latestRunTime; |
| 73 | /** Set by the SyncManager in order to delay retries. */ |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 74 | public Long backoff; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 75 | /** Specified by the adapter to delay subsequent sync operations. */ |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 76 | public long delayUntil; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 77 | /** |
| 78 | * Elapsed real time in millis when this sync will be run. |
| 79 | * Depends on max(backoff, latestRunTime, and delayUntil). |
| 80 | */ |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 81 | public long effectiveRunTime; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 82 | /** Amount of time before {@link effectiveRunTime} from which this sync can run. */ |
| 83 | public long flexTime; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 84 | |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 85 | public SyncOperation(Account account, int userId, int reason, int source, String authority, |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 86 | Bundle extras, long runTimeFromNow, long flexTime, long backoff, |
| 87 | long delayUntil, boolean allowParallelSyncs) { |
| 88 | this.service = null; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 89 | this.account = account; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 90 | this.authority = authority; |
Amith Yamasani | 04e0d26 | 2012-02-14 11:50:53 -0800 | [diff] [blame] | 91 | this.userId = userId; |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 92 | this.reason = reason; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 93 | this.syncSource = source; |
Fred Quintana | 0c4d04a | 2010-11-03 17:02:55 -0700 | [diff] [blame] | 94 | this.allowParallelSyncs = allowParallelSyncs; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 95 | this.extras = new Bundle(extras); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 96 | cleanBundle(this.extras); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 97 | this.delayUntil = delayUntil; |
| 98 | this.backoff = backoff; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 99 | final long now = SystemClock.elapsedRealtime(); |
Matthew Williams | 68e39c3 | 2013-07-25 16:40:23 -0700 | [diff] [blame] | 100 | // Checks the extras bundle. Must occur after we set the internal bundle. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 101 | if (runTimeFromNow < 0 || isExpedited()) { |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 102 | this.expedited = true; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 103 | this.latestRunTime = now; |
| 104 | this.flexTime = 0; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 105 | } else { |
| 106 | this.expedited = false; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 107 | this.latestRunTime = now + runTimeFromNow; |
| 108 | this.flexTime = flexTime; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 109 | } |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 110 | updateEffectiveRunTime(); |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 111 | this.key = toKey(); |
| 112 | } |
| 113 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 114 | /** |
| 115 | * Make sure the bundle attached to this SyncOperation doesn't have unnecessary |
| 116 | * flags set. |
| 117 | * @param bundle to clean. |
| 118 | */ |
| 119 | private void cleanBundle(Bundle bundle) { |
| 120 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_UPLOAD); |
| 121 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_MANUAL); |
| 122 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS); |
| 123 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); |
| 124 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY); |
| 125 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS); |
| 126 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_EXPEDITED); |
| 127 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS); |
Matthew Williams | 6222288 | 2013-08-20 15:32:20 -0700 | [diff] [blame] | 128 | removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISALLOW_METERED); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 129 | |
| 130 | // Remove Config data. |
| 131 | bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD); |
| 132 | bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD); |
| 133 | } |
| 134 | |
| 135 | private void removeFalseExtra(Bundle bundle, String extraName) { |
| 136 | if (!bundle.getBoolean(extraName, false)) { |
| 137 | bundle.remove(extraName); |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 138 | } |
| 139 | } |
| 140 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 141 | /** Only used to immediately reschedule a sync. */ |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 142 | SyncOperation(SyncOperation other) { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 143 | this.service = other.service; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 144 | this.account = other.account; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 145 | this.authority = other.authority; |
Amith Yamasani | 04e0d26 | 2012-02-14 11:50:53 -0800 | [diff] [blame] | 146 | this.userId = other.userId; |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 147 | this.reason = other.reason; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 148 | this.syncSource = other.syncSource; |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 149 | this.extras = new Bundle(other.extras); |
| 150 | this.expedited = other.expedited; |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 151 | this.latestRunTime = SystemClock.elapsedRealtime(); |
| 152 | this.flexTime = 0L; |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 153 | this.backoff = other.backoff; |
Fred Quintana | 0c4d04a | 2010-11-03 17:02:55 -0700 | [diff] [blame] | 154 | this.allowParallelSyncs = other.allowParallelSyncs; |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 155 | this.updateEffectiveRunTime(); |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 156 | this.key = toKey(); |
| 157 | } |
| 158 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 159 | @Override |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 160 | public String toString() { |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 161 | return dump(null, true); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 162 | } |
| 163 | |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 164 | public String dump(PackageManager pm, boolean useOneLine) { |
Alon Albert | 8e28555 | 2012-09-17 15:05:27 -0700 | [diff] [blame] | 165 | StringBuilder sb = new StringBuilder() |
| 166 | .append(account.name) |
| 167 | .append(" u") |
| 168 | .append(userId).append(" (") |
| 169 | .append(account.type) |
| 170 | .append(")") |
| 171 | .append(", ") |
| 172 | .append(authority) |
| 173 | .append(", ") |
| 174 | .append(SyncStorageEngine.SOURCES[syncSource]) |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 175 | .append(", latestRunTime ") |
| 176 | .append(latestRunTime); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 177 | if (expedited) { |
| 178 | sb.append(", EXPEDITED"); |
| 179 | } |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 180 | sb.append(", reason: "); |
| 181 | sb.append(reasonToString(pm, reason)); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 182 | if (!useOneLine && !extras.keySet().isEmpty()) { |
| 183 | sb.append("\n "); |
| 184 | extrasToStringBuilder(extras, sb); |
| 185 | } |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 186 | return sb.toString(); |
| 187 | } |
| 188 | |
Alon Albert | 57286f9 | 2012-10-09 14:21:38 -0700 | [diff] [blame] | 189 | public static String reasonToString(PackageManager pm, int reason) { |
| 190 | if (reason >= 0) { |
| 191 | if (pm != null) { |
| 192 | final String[] packages = pm.getPackagesForUid(reason); |
| 193 | if (packages != null && packages.length == 1) { |
| 194 | return packages[0]; |
| 195 | } |
| 196 | final String name = pm.getNameForUid(reason); |
| 197 | if (name != null) { |
| 198 | return name; |
| 199 | } |
| 200 | return String.valueOf(reason); |
| 201 | } else { |
| 202 | return String.valueOf(reason); |
| 203 | } |
| 204 | } else { |
| 205 | final int index = -reason - 1; |
| 206 | if (index >= REASON_NAMES.length) { |
| 207 | return String.valueOf(reason); |
| 208 | } else { |
| 209 | return REASON_NAMES[index]; |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | |
Matthew Williams | 6222288 | 2013-08-20 15:32:20 -0700 | [diff] [blame] | 214 | public boolean isMeteredDisallowed() { |
| 215 | return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 216 | } |
| 217 | |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 218 | public boolean isInitialization() { |
| 219 | return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); |
| 220 | } |
| 221 | |
Fred Quintana | dc47556 | 2012-05-04 15:51:54 -0700 | [diff] [blame] | 222 | public boolean isExpedited() { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 223 | return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false) || expedited; |
Fred Quintana | dc47556 | 2012-05-04 15:51:54 -0700 | [diff] [blame] | 224 | } |
| 225 | |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 226 | public boolean ignoreBackoff() { |
| 227 | return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); |
| 228 | } |
| 229 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 230 | /** Changed in V3. */ |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 231 | private String toKey() { |
| 232 | StringBuilder sb = new StringBuilder(); |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 233 | if (service == null) { |
| 234 | sb.append("authority: ").append(authority); |
| 235 | sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type |
| 236 | + "}"); |
| 237 | } else { |
| 238 | sb.append("service {package=" ) |
| 239 | .append(service.getPackageName()) |
| 240 | .append(" user=") |
| 241 | .append(userId) |
| 242 | .append(", class=") |
| 243 | .append(service.getClassName()) |
| 244 | .append("}"); |
| 245 | } |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 246 | sb.append(" extras: "); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 247 | extrasToStringBuilder(extras, sb); |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 248 | return sb.toString(); |
| 249 | } |
| 250 | |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 251 | public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) { |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 252 | sb.append("["); |
| 253 | for (String key : bundle.keySet()) { |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 254 | sb.append(key).append("=").append(bundle.get(key)).append(" "); |
| 255 | } |
| 256 | sb.append("]"); |
| 257 | } |
| 258 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 259 | /** |
| 260 | * Update the effective run time of this Operation based on latestRunTime (specified at |
| 261 | * creation time of sync), delayUntil (specified by SyncAdapter), or backoff (specified by |
| 262 | * SyncManager on soft failures). |
| 263 | */ |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 264 | public void updateEffectiveRunTime() { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 265 | // Regardless of whether we're in backoff or honouring a delayUntil, we still incorporate |
| 266 | // the flex time provided by the developer. |
| 267 | effectiveRunTime = ignoreBackoff() ? |
| 268 | latestRunTime : |
| 269 | Math.max(Math.max(latestRunTime, delayUntil), backoff); |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 270 | } |
| 271 | |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 272 | /** |
Matthew Williams | 7986fe4 | 2013-07-29 16:56:23 -0700 | [diff] [blame] | 273 | * SyncOperations are sorted based on their earliest effective run time. |
| 274 | * This comparator is used to sort the SyncOps at a given time when |
| 275 | * deciding which to run, so earliest run time is the best criteria. |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 276 | */ |
| 277 | @Override |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 278 | public int compareTo(Object o) { |
Matthew Williams | fa77418 | 2013-06-18 15:44:11 -0700 | [diff] [blame] | 279 | SyncOperation other = (SyncOperation) o; |
Fred Quintana | 918339a | 2010-10-05 14:00:39 -0700 | [diff] [blame] | 280 | if (expedited != other.expedited) { |
| 281 | return expedited ? -1 : 1; |
| 282 | } |
Matthew Williams | 7986fe4 | 2013-07-29 16:56:23 -0700 | [diff] [blame] | 283 | long thisIntervalStart = Math.max(effectiveRunTime - flexTime, 0); |
| 284 | long otherIntervalStart = Math.max( |
| 285 | other.effectiveRunTime - other.flexTime, 0); |
| 286 | if (thisIntervalStart < otherIntervalStart) { |
| 287 | return -1; |
| 288 | } else if (otherIntervalStart < thisIntervalStart) { |
| 289 | return 1; |
| 290 | } else { |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 291 | return 0; |
| 292 | } |
Fred Quintana | 307da1a | 2010-01-21 14:24:20 -0800 | [diff] [blame] | 293 | } |
| 294 | } |