SyncStatusInfo.java revision fdc5723076394fd79380688e7e5b5226d199cd31
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    private static final String TAG = "Sync";
28
29    static final int VERSION = 4;
30
31    private static final int MAX_EVENT_COUNT = 10;
32
33    public final int authorityId;
34    public long totalElapsedTime;
35    public int numSyncs;
36    public int numSourcePoll;
37    public int numSourceServer;
38    public int numSourceLocal;
39    public int numSourceUser;
40    public int numSourcePeriodic;
41    public long lastSuccessTime;
42    public int lastSuccessSource;
43    public long lastFailureTime;
44    public int lastFailureSource;
45    public String lastFailureMesg;
46    public long initialFailureTime;
47    public boolean pending;
48    public boolean initialize;
49
50  // Warning: It is up to the external caller to ensure there are
51  // no race conditions when accessing this list
52  private ArrayList<Long> periodicSyncTimes;
53
54    private final ArrayList<Long> mLastEventTimes = new ArrayList<>();
55    private final ArrayList<String> mLastEvents = new ArrayList<>();
56
57    public SyncStatusInfo(int authorityId) {
58        this.authorityId = authorityId;
59    }
60
61    public int getLastFailureMesgAsInt(int def) {
62        final int i = ContentResolver.syncErrorStringToInt(lastFailureMesg);
63        if (i > 0) {
64            return i;
65        } else {
66            Log.d(TAG, "Unknown lastFailureMesg:" + lastFailureMesg);
67            return def;
68        }
69    }
70
71    public int describeContents() {
72        return 0;
73    }
74
75    public void writeToParcel(Parcel parcel, int flags) {
76        parcel.writeInt(VERSION);
77        parcel.writeInt(authorityId);
78        parcel.writeLong(totalElapsedTime);
79        parcel.writeInt(numSyncs);
80        parcel.writeInt(numSourcePoll);
81        parcel.writeInt(numSourceServer);
82        parcel.writeInt(numSourceLocal);
83        parcel.writeInt(numSourceUser);
84        parcel.writeLong(lastSuccessTime);
85        parcel.writeInt(lastSuccessSource);
86        parcel.writeLong(lastFailureTime);
87        parcel.writeInt(lastFailureSource);
88        parcel.writeString(lastFailureMesg);
89        parcel.writeLong(initialFailureTime);
90        parcel.writeInt(pending ? 1 : 0);
91        parcel.writeInt(initialize ? 1 : 0);
92        if (periodicSyncTimes != null) {
93            parcel.writeInt(periodicSyncTimes.size());
94            for (long periodicSyncTime : periodicSyncTimes) {
95                parcel.writeLong(periodicSyncTime);
96            }
97        } else {
98            parcel.writeInt(-1);
99        }
100        parcel.writeInt(mLastEventTimes.size());
101        for (int i = 0; i < mLastEventTimes.size(); i++) {
102            parcel.writeLong(mLastEventTimes.get(i));
103            parcel.writeString(mLastEvents.get(i));
104        }
105        parcel.writeInt(numSourcePeriodic);
106    }
107
108    public SyncStatusInfo(Parcel parcel) {
109        int version = parcel.readInt();
110        if (version != VERSION && version != 1) {
111            Log.w("SyncStatusInfo", "Unknown version: " + version);
112        }
113        authorityId = parcel.readInt();
114        totalElapsedTime = parcel.readLong();
115        numSyncs = parcel.readInt();
116        numSourcePoll = parcel.readInt();
117        numSourceServer = parcel.readInt();
118        numSourceLocal = parcel.readInt();
119        numSourceUser = parcel.readInt();
120        lastSuccessTime = parcel.readLong();
121        lastSuccessSource = parcel.readInt();
122        lastFailureTime = parcel.readLong();
123        lastFailureSource = parcel.readInt();
124        lastFailureMesg = parcel.readString();
125        initialFailureTime = parcel.readLong();
126        pending = parcel.readInt() != 0;
127        initialize = parcel.readInt() != 0;
128        if (version == 1) {
129            periodicSyncTimes = null;
130        } else {
131            final int count = parcel.readInt();
132            if (count < 0) {
133                periodicSyncTimes = null;
134            } else {
135                periodicSyncTimes = new ArrayList<Long>();
136                for (int i = 0; i < count; i++) {
137                    periodicSyncTimes.add(parcel.readLong());
138                }
139            }
140            if (version >= 3) {
141                mLastEventTimes.clear();
142                mLastEvents.clear();
143                final int nEvents = parcel.readInt();
144                for (int i = 0; i < nEvents; i++) {
145                    mLastEventTimes.add(parcel.readLong());
146                    mLastEvents.add(parcel.readString());
147                }
148            }
149        }
150        if (version < 4) {
151            // Before version 4, numSourcePeriodic wasn't persisted.
152            numSourcePeriodic = numSyncs - numSourceLocal - numSourcePoll - numSourceServer
153                    - numSourceUser;
154            if (numSourcePeriodic < 0) { // Sanity check.
155                numSourcePeriodic = 0;
156            }
157        } else {
158            numSourcePeriodic = parcel.readInt();
159        }
160    }
161
162    public SyncStatusInfo(SyncStatusInfo other) {
163        authorityId = other.authorityId;
164        totalElapsedTime = other.totalElapsedTime;
165        numSyncs = other.numSyncs;
166        numSourcePoll = other.numSourcePoll;
167        numSourceServer = other.numSourceServer;
168        numSourceLocal = other.numSourceLocal;
169        numSourceUser = other.numSourceUser;
170        numSourcePeriodic = other.numSourcePeriodic;
171        lastSuccessTime = other.lastSuccessTime;
172        lastSuccessSource = other.lastSuccessSource;
173        lastFailureTime = other.lastFailureTime;
174        lastFailureSource = other.lastFailureSource;
175        lastFailureMesg = other.lastFailureMesg;
176        initialFailureTime = other.initialFailureTime;
177        pending = other.pending;
178        initialize = other.initialize;
179        if (other.periodicSyncTimes != null) {
180            periodicSyncTimes = new ArrayList<Long>(other.periodicSyncTimes);
181        }
182        mLastEventTimes.addAll(other.mLastEventTimes);
183        mLastEvents.addAll(other.mLastEvents);
184    }
185
186    public void setPeriodicSyncTime(int index, long when) {
187        // The list is initialized lazily when scheduling occurs so we need to make sure
188        // we initialize elements < index to zero (zero is ignore for scheduling purposes)
189        ensurePeriodicSyncTimeSize(index);
190        periodicSyncTimes.set(index, when);
191    }
192
193    public long getPeriodicSyncTime(int index) {
194        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
195            return periodicSyncTimes.get(index);
196        } else {
197            return 0;
198        }
199    }
200
201    public void removePeriodicSyncTime(int index) {
202        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
203            periodicSyncTimes.remove(index);
204        }
205    }
206
207    /** */
208    public void addEvent(String message) {
209        if (mLastEventTimes.size() >= MAX_EVENT_COUNT) {
210            mLastEventTimes.remove(MAX_EVENT_COUNT - 1);
211            mLastEvents.remove(MAX_EVENT_COUNT - 1);
212        }
213        mLastEventTimes.add(0, System.currentTimeMillis());
214        mLastEvents.add(0, message);
215    }
216
217    /** */
218    public int getEventCount() {
219        return mLastEventTimes.size();
220    }
221
222    /** */
223    public long getEventTime(int i) {
224        return mLastEventTimes.get(i);
225    }
226
227    /** */
228    public String getEvent(int i) {
229        return mLastEvents.get(i);
230    }
231
232    public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
233        public SyncStatusInfo createFromParcel(Parcel in) {
234            return new SyncStatusInfo(in);
235        }
236
237        public SyncStatusInfo[] newArray(int size) {
238            return new SyncStatusInfo[size];
239        }
240    };
241
242    private void ensurePeriodicSyncTimeSize(int index) {
243        if (periodicSyncTimes == null) {
244            periodicSyncTimes = new ArrayList<Long>(0);
245        }
246
247        final int requiredSize = index + 1;
248        if (periodicSyncTimes.size() < requiredSize) {
249            for (int i = periodicSyncTimes.size(); i < requiredSize; i++) {
250                periodicSyncTimes.add((long) 0);
251            }
252        }
253    }
254}