Home | History | Annotate | Download | only in content
      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