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 17 package android.content; 18 19 import android.accounts.Account; 20 import android.os.Bundle; 21 import android.os.SystemClock; 22 23 /** 24 * Value type that represents a sync operation. 25 * @hide 26 */ 27 public class SyncOperation implements Comparable { 28 public final Account account; 29 public int syncSource; 30 public String authority; 31 public final boolean allowParallelSyncs; 32 public Bundle extras; 33 public final String key; 34 public long earliestRunTime; 35 public boolean expedited; 36 public SyncStorageEngine.PendingOperation pendingOperation; 37 public Long backoff; 38 public long delayUntil; 39 public long effectiveRunTime; 40 41 public SyncOperation(Account account, int source, String authority, Bundle extras, 42 long delayInMs, long backoff, long delayUntil, boolean allowParallelSyncs) { 43 this.account = account; 44 this.syncSource = source; 45 this.authority = authority; 46 this.allowParallelSyncs = allowParallelSyncs; 47 this.extras = new Bundle(extras); 48 removeFalseExtra(ContentResolver.SYNC_EXTRAS_UPLOAD); 49 removeFalseExtra(ContentResolver.SYNC_EXTRAS_MANUAL); 50 removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS); 51 removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); 52 removeFalseExtra(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY); 53 removeFalseExtra(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS); 54 removeFalseExtra(ContentResolver.SYNC_EXTRAS_EXPEDITED); 55 removeFalseExtra(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS); 56 this.delayUntil = delayUntil; 57 this.backoff = backoff; 58 final long now = SystemClock.elapsedRealtime(); 59 if (delayInMs < 0) { 60 this.expedited = true; 61 this.earliestRunTime = now; 62 } else { 63 this.expedited = false; 64 this.earliestRunTime = now + delayInMs; 65 } 66 updateEffectiveRunTime(); 67 this.key = toKey(); 68 } 69 70 private void removeFalseExtra(String extraName) { 71 if (!extras.getBoolean(extraName, false)) { 72 extras.remove(extraName); 73 } 74 } 75 76 SyncOperation(SyncOperation other) { 77 this.account = other.account; 78 this.syncSource = other.syncSource; 79 this.authority = other.authority; 80 this.extras = new Bundle(other.extras); 81 this.expedited = other.expedited; 82 this.earliestRunTime = SystemClock.elapsedRealtime(); 83 this.backoff = other.backoff; 84 this.delayUntil = other.delayUntil; 85 this.allowParallelSyncs = other.allowParallelSyncs; 86 this.updateEffectiveRunTime(); 87 this.key = toKey(); 88 } 89 90 public String toString() { 91 return dump(true); 92 } 93 94 public String dump(boolean useOneLine) { 95 StringBuilder sb = new StringBuilder(); 96 sb.append(account.name); 97 sb.append(" (" + account.type + ")"); 98 sb.append(", " + authority); 99 sb.append(", "); 100 sb.append(SyncStorageEngine.SOURCES[syncSource]); 101 sb.append(", earliestRunTime " + earliestRunTime); 102 if (expedited) { 103 sb.append(", EXPEDITED"); 104 } 105 if (!useOneLine && !extras.keySet().isEmpty()) { 106 sb.append("\n "); 107 extrasToStringBuilder(extras, sb); 108 } 109 return sb.toString(); 110 } 111 112 public boolean isInitialization() { 113 return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); 114 } 115 116 public boolean ignoreBackoff() { 117 return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); 118 } 119 120 private String toKey() { 121 StringBuilder sb = new StringBuilder(); 122 sb.append("authority: ").append(authority); 123 sb.append(" account {name=" + account.name + ", type=" + account.type + "}"); 124 sb.append(" extras: "); 125 extrasToStringBuilder(extras, sb); 126 return sb.toString(); 127 } 128 129 public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) { 130 sb.append("["); 131 for (String key : bundle.keySet()) { 132 sb.append(key).append("=").append(bundle.get(key)).append(" "); 133 } 134 sb.append("]"); 135 } 136 137 public void updateEffectiveRunTime() { 138 effectiveRunTime = ignoreBackoff() 139 ? earliestRunTime 140 : Math.max( 141 Math.max(earliestRunTime, delayUntil), 142 backoff); 143 } 144 145 public int compareTo(Object o) { 146 SyncOperation other = (SyncOperation)o; 147 148 if (expedited != other.expedited) { 149 return expedited ? -1 : 1; 150 } 151 152 if (effectiveRunTime == other.effectiveRunTime) { 153 return 0; 154 } 155 156 return effectiveRunTime < other.effectiveRunTime ? -1 : 1; 157 } 158 } 159