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 SyncOperation(Account account, int source, String authority, Bundle extras, long delayInMs, long backoff, long delayUntil, boolean allowParallelSyncs)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 removeFalseExtra(String extraName)70 private void removeFalseExtra(String extraName) { 71 if (!extras.getBoolean(extraName, false)) { 72 extras.remove(extraName); 73 } 74 } 75 SyncOperation(SyncOperation other)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 toString()90 public String toString() { 91 return dump(true); 92 } 93 dump(boolean useOneLine)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 isInitialization()112 public boolean isInitialization() { 113 return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false); 114 } 115 ignoreBackoff()116 public boolean ignoreBackoff() { 117 return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false); 118 } 119 toKey()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 extrasToStringBuilder(Bundle bundle, StringBuilder sb)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 updateEffectiveRunTime()137 public void updateEffectiveRunTime() { 138 effectiveRunTime = ignoreBackoff() 139 ? earliestRunTime 140 : Math.max( 141 Math.max(earliestRunTime, delayUntil), 142 backoff); 143 } 144 compareTo(Object o)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