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