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
17package android.content;
18
19import android.accounts.Account;
20import android.os.Bundle;
21import android.os.SystemClock;
22
23/**
24 * Value type that represents a sync operation.
25 * @hide
26 */
27public class SyncOperation implements Comparable {
28    public final Account account;
29    public int syncSource;
30    public String authority;
31    public Bundle extras;
32    public final String key;
33    public long earliestRunTime;
34    public boolean expedited;
35    public SyncStorageEngine.PendingOperation pendingOperation;
36
37    public SyncOperation(Account account, int source, String authority, Bundle extras,
38            long delayInMs) {
39        this.account = account;
40        this.syncSource = source;
41        this.authority = authority;
42        this.extras = new Bundle(extras);
43        removeFalseExtra(ContentResolver.SYNC_EXTRAS_UPLOAD);
44        removeFalseExtra(ContentResolver.SYNC_EXTRAS_MANUAL);
45        removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS);
46        removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
47        removeFalseExtra(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY);
48        removeFalseExtra(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS);
49        removeFalseExtra(ContentResolver.SYNC_EXTRAS_EXPEDITED);
50        removeFalseExtra(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
51        final long now = SystemClock.elapsedRealtime();
52        if (delayInMs < 0) {
53            this.expedited = true;
54            this.earliestRunTime = now;
55        } else {
56            this.expedited = false;
57            this.earliestRunTime = now + delayInMs;
58        }
59        this.key = toKey();
60    }
61
62    private void removeFalseExtra(String extraName) {
63        if (!extras.getBoolean(extraName, false)) {
64            extras.remove(extraName);
65        }
66    }
67
68    SyncOperation(SyncOperation other) {
69        this.account = other.account;
70        this.syncSource = other.syncSource;
71        this.authority = other.authority;
72        this.extras = new Bundle(other.extras);
73        this.expedited = other.expedited;
74        this.earliestRunTime = SystemClock.elapsedRealtime();
75        this.key = toKey();
76    }
77
78    public String toString() {
79        StringBuilder sb = new StringBuilder();
80        sb.append("authority: ").append(authority);
81        sb.append(" account: ").append(account);
82        sb.append(" extras: ");
83        extrasToStringBuilder(extras, sb, false /* asKey */);
84        sb.append(" syncSource: ").append(syncSource);
85        sb.append(" when: ").append(earliestRunTime);
86        sb.append(" expedited: ").append(expedited);
87        return sb.toString();
88    }
89
90    private String toKey() {
91        StringBuilder sb = new StringBuilder();
92        sb.append("authority: ").append(authority);
93	sb.append(" account {name=" + account.name + ", type=" + account.type + "}");
94        sb.append(" extras: ");
95        extrasToStringBuilder(extras, sb, true /* asKey */);
96        return sb.toString();
97    }
98
99    public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb, boolean asKey) {
100        sb.append("[");
101        for (String key : bundle.keySet()) {
102            // if we are writing this as a key don't consider whether this
103            // is an initialization sync or not when computing the key since
104            // we set this flag appropriately when dispatching the sync request.
105            if (asKey && ContentResolver.SYNC_EXTRAS_INITIALIZE.equals(key)) {
106                continue;
107            }
108            sb.append(key).append("=").append(bundle.get(key)).append(" ");
109        }
110        sb.append("]");
111    }
112
113    public int compareTo(Object o) {
114        SyncOperation other = (SyncOperation)o;
115        if (earliestRunTime == other.earliestRunTime) {
116            return 0;
117        }
118        return (earliestRunTime < other.earliestRunTime) ? -1 : 1;
119    }
120}
121