1/*
2 * Copyright (C) 2009 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.os.Parcel;
20import android.os.Parcelable;
21import android.util.Log;
22
23import java.util.ArrayList;
24
25/** @hide */
26public class SyncStatusInfo implements Parcelable {
27    static final int VERSION = 2;
28
29    public final int authorityId;
30    public long totalElapsedTime;
31    public int numSyncs;
32    public int numSourcePoll;
33    public int numSourceServer;
34    public int numSourceLocal;
35    public int numSourceUser;
36    public int numSourcePeriodic;
37    public long lastSuccessTime;
38    public int lastSuccessSource;
39    public long lastFailureTime;
40    public int lastFailureSource;
41    public String lastFailureMesg;
42    public long initialFailureTime;
43    public boolean pending;
44    public boolean initialize;
45
46  // Warning: It is up to the external caller to ensure there are
47  // no race conditions when accessing this list
48  private ArrayList<Long> periodicSyncTimes;
49
50    private static final String TAG = "Sync";
51
52    public SyncStatusInfo(int authorityId) {
53        this.authorityId = authorityId;
54    }
55
56    public int getLastFailureMesgAsInt(int def) {
57        final int i = ContentResolver.syncErrorStringToInt(lastFailureMesg);
58        if (i > 0) {
59            return i;
60        } else {
61            Log.d(TAG, "Unknown lastFailureMesg:" + lastFailureMesg);
62            return def;
63        }
64    }
65
66    public int describeContents() {
67        return 0;
68    }
69
70    public void writeToParcel(Parcel parcel, int flags) {
71        parcel.writeInt(VERSION);
72        parcel.writeInt(authorityId);
73        parcel.writeLong(totalElapsedTime);
74        parcel.writeInt(numSyncs);
75        parcel.writeInt(numSourcePoll);
76        parcel.writeInt(numSourceServer);
77        parcel.writeInt(numSourceLocal);
78        parcel.writeInt(numSourceUser);
79        parcel.writeLong(lastSuccessTime);
80        parcel.writeInt(lastSuccessSource);
81        parcel.writeLong(lastFailureTime);
82        parcel.writeInt(lastFailureSource);
83        parcel.writeString(lastFailureMesg);
84        parcel.writeLong(initialFailureTime);
85        parcel.writeInt(pending ? 1 : 0);
86        parcel.writeInt(initialize ? 1 : 0);
87        if (periodicSyncTimes != null) {
88            parcel.writeInt(periodicSyncTimes.size());
89            for (long periodicSyncTime : periodicSyncTimes) {
90                parcel.writeLong(periodicSyncTime);
91            }
92        } else {
93            parcel.writeInt(-1);
94        }
95    }
96
97    public SyncStatusInfo(Parcel parcel) {
98        int version = parcel.readInt();
99        if (version != VERSION && version != 1) {
100            Log.w("SyncStatusInfo", "Unknown version: " + version);
101        }
102        authorityId = parcel.readInt();
103        totalElapsedTime = parcel.readLong();
104        numSyncs = parcel.readInt();
105        numSourcePoll = parcel.readInt();
106        numSourceServer = parcel.readInt();
107        numSourceLocal = parcel.readInt();
108        numSourceUser = parcel.readInt();
109        lastSuccessTime = parcel.readLong();
110        lastSuccessSource = parcel.readInt();
111        lastFailureTime = parcel.readLong();
112        lastFailureSource = parcel.readInt();
113        lastFailureMesg = parcel.readString();
114        initialFailureTime = parcel.readLong();
115        pending = parcel.readInt() != 0;
116        initialize = parcel.readInt() != 0;
117        if (version == 1) {
118            periodicSyncTimes = null;
119        } else {
120            int N = parcel.readInt();
121            if (N < 0) {
122                periodicSyncTimes = null;
123            } else {
124                periodicSyncTimes = new ArrayList<Long>();
125                for (int i=0; i<N; i++) {
126                    periodicSyncTimes.add(parcel.readLong());
127                }
128            }
129        }
130    }
131
132    public SyncStatusInfo(SyncStatusInfo other) {
133        authorityId = other.authorityId;
134        totalElapsedTime = other.totalElapsedTime;
135        numSyncs = other.numSyncs;
136        numSourcePoll = other.numSourcePoll;
137        numSourceServer = other.numSourceServer;
138        numSourceLocal = other.numSourceLocal;
139        numSourceUser = other.numSourceUser;
140        numSourcePeriodic = other.numSourcePeriodic;
141        lastSuccessTime = other.lastSuccessTime;
142        lastSuccessSource = other.lastSuccessSource;
143        lastFailureTime = other.lastFailureTime;
144        lastFailureSource = other.lastFailureSource;
145        lastFailureMesg = other.lastFailureMesg;
146        initialFailureTime = other.initialFailureTime;
147        pending = other.pending;
148        initialize = other.initialize;
149        if (other.periodicSyncTimes != null) {
150            periodicSyncTimes = new ArrayList<Long>(other.periodicSyncTimes);
151        }
152    }
153
154    public void setPeriodicSyncTime(int index, long when) {
155        // The list is initialized lazily when scheduling occurs so we need to make sure
156        // we initialize elements < index to zero (zero is ignore for scheduling purposes)
157        ensurePeriodicSyncTimeSize(index);
158        periodicSyncTimes.set(index, when);
159    }
160
161    public long getPeriodicSyncTime(int index) {
162        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
163            return periodicSyncTimes.get(index);
164        } else {
165            return 0;
166        }
167    }
168
169    public void removePeriodicSyncTime(int index) {
170        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
171            periodicSyncTimes.remove(index);
172        }
173    }
174
175    public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
176        public SyncStatusInfo createFromParcel(Parcel in) {
177            return new SyncStatusInfo(in);
178        }
179
180        public SyncStatusInfo[] newArray(int size) {
181            return new SyncStatusInfo[size];
182        }
183    };
184
185    private void ensurePeriodicSyncTimeSize(int index) {
186        if (periodicSyncTimes == null) {
187            periodicSyncTimes = new ArrayList<Long>(0);
188        }
189
190        final int requiredSize = index + 1;
191        if (periodicSyncTimes.size() < requiredSize) {
192            for (int i = periodicSyncTimes.size(); i < requiredSize; i++) {
193                periodicSyncTimes.add((long) 0);
194            }
195        }
196    }
197}