Skip to content

Commit e0bde33

Browse files
committed
Add Detailed Sync Stats Section
Also improve history formatting Here's a smaple of what it looks like: Detailed Statistics (Recent history): 20 40s ------------------------------------------------------------------------------------- com.android.contacts : 9/45% 11/27% [email protected]/com.google : 3/15% 4/11% [email protected]/com.google : 3/15% 3/9% [email protected]/com.google : 3/15% 2/6% ------------------------------------------------------------------------------------- gmail-ls : 6/30% 22/56% ------------------------------------------------------------------------------------- com.android.calendar : 3/15% 5/14% [email protected]/com.google : 1/5% 4/12% [email protected]/com.google : 1/5% 0/0% [email protected]/com.google : 1/5% 0/0% ------------------------------------------------------------------------------------- com.google.android.apps.plus.content.EsGooglePhotoProvider : 2/10% 0/1% [email protected]/com.google : 1/5% 0/1% [email protected]/com.google : 1/5% 0/0% ------------------------------------------------------------------------------------- Recent Sync History #1 : 2011-09-23 15:18:35 SERVER 0.8s [email protected]/com.google gmail-ls #2 : 2011-09-23 15:17:56 SERVER 1.3s 00:38 zsol#3 : 2011-09-23 15:17:52 SERVER 4.6s 00:04 #4 : 2011-09-23 15:17:45 SERVER 1.7s 00:06 #5 : 2011-09-23 15:16:51 LOCAL 0.8s [email protected]/com.google com.android.contacts #6 : 2011-09-23 15:16:51 LOCAL 0.7s [email protected]/com.google com.android.contacts #7 : 2011-09-23 15:16:50 LOCAL 0.7s [email protected]/com.google com.android.contacts #8 : 2011-09-23 15:15:35 LOCAL 0.7s [email protected]/com.google com.android.contacts #9 : 2011-09-23 15:15:34 LOCAL 0.8s [email protected]/com.google com.android.contacts #10 : 2011-09-23 15:15:33 LOCAL 1.9s [email protected]/com.google com.android.contacts #11 : 2011-09-23 15:14:37 LOCAL 1.3s [email protected]/com.google com.android.contacts #12 : 2011-09-23 15:14:35 LOCAL 2.0s [email protected]/com.google com.android.contacts #13 : 2011-09-23 15:14:32 LOCAL 2.2s [email protected]/com.google com.android.contacts #14 : 2011-09-23 15:13:41 SERVER 1.3s [email protected]/com.google gmail-ls #15 : 2011-09-23 15:13:34 LOCAL 0.3s [email protected]/com.google com.android.calendar #16 : 2011-09-23 15:13:34 LOCAL 0.4s [email protected]/com.google com.android.calendar #17 : 2011-09-23 15:13:33 SERVER 0.1s [email protected]/com.google com.google.android.apps.plus.content.EsGooglePhotoProvider #18 : 2011-09-23 15:13:33 SERVER 0.5s [email protected]/com.google com.google.android.apps.plus.content.EsGooglePhotoProvider #19 : 2011-09-23 15:13:29 LOCAL 4.9s [email protected]/com.google com.android.calendar #20 : 2011-09-23 15:13:28 SERVER 13.1s [email protected]/com.google gmail-ls Change-Id: Idc904e2e18a373b6d2d10af65b02683c11fd8d90
1 parent 64061c3 commit e0bde33

File tree

1 file changed

+232
-62
lines changed

1 file changed

+232
-62
lines changed

core/java/android/content/SyncManager.java

Lines changed: 232 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,10 @@
1616

1717
package android.content;
1818

19-
import android.os.Bundle;
20-
import android.os.Handler;
21-
import android.os.HandlerThread;
22-
import android.os.IBinder;
23-
import android.os.Looper;
24-
import android.os.Message;
25-
import android.os.PowerManager;
26-
import android.os.Process;
27-
import android.os.RemoteException;
28-
import android.os.SystemClock;
29-
import android.os.SystemProperties;
30-
import com.google.android.collect.Lists;
31-
import com.google.android.collect.Maps;
32-
3319
import com.android.internal.R;
3420
import com.android.internal.util.ArrayUtils;
21+
import com.google.android.collect.Lists;
22+
import com.google.android.collect.Maps;
3523

3624
import android.accounts.Account;
3725
import android.accounts.AccountManager;
@@ -42,12 +30,23 @@
4230
import android.app.PendingIntent;
4331
import android.content.pm.ApplicationInfo;
4432
import android.content.pm.PackageManager;
45-
import android.content.pm.ResolveInfo;
46-
import android.content.pm.RegisteredServicesCache;
4733
import android.content.pm.ProviderInfo;
34+
import android.content.pm.RegisteredServicesCache;
4835
import android.content.pm.RegisteredServicesCacheListener;
36+
import android.content.pm.ResolveInfo;
4937
import android.net.ConnectivityManager;
5038
import android.net.NetworkInfo;
39+
import android.os.Bundle;
40+
import android.os.Handler;
41+
import android.os.HandlerThread;
42+
import android.os.IBinder;
43+
import android.os.Looper;
44+
import android.os.Message;
45+
import android.os.PowerManager;
46+
import android.os.Process;
47+
import android.os.RemoteException;
48+
import android.os.SystemClock;
49+
import android.os.SystemProperties;
5150
import android.os.WorkSource;
5251
import android.provider.Settings;
5352
import android.text.format.DateUtils;
@@ -59,12 +58,15 @@
5958
import java.io.FileDescriptor;
6059
import java.io.PrintWriter;
6160
import java.util.ArrayList;
61+
import java.util.Arrays;
6262
import java.util.Collection;
6363
import java.util.Collections;
64+
import java.util.Comparator;
6465
import java.util.HashMap;
6566
import java.util.HashSet;
6667
import java.util.Iterator;
6768
import java.util.List;
69+
import java.util.Map;
6870
import java.util.Random;
6971
import java.util.concurrent.CountDownLatch;
7072

@@ -1006,9 +1008,8 @@ public void binderDied() {
10061008
}
10071009

10081010
protected void dump(FileDescriptor fd, PrintWriter pw) {
1009-
StringBuilder sb = new StringBuilder();
1010-
dumpSyncState(pw, sb);
1011-
dumpSyncHistory(pw, sb);
1011+
dumpSyncState(pw);
1012+
dumpSyncHistory(pw);
10121013

10131014
pw.println();
10141015
pw.println("SyncAdapters:");
@@ -1023,7 +1024,7 @@ static String formatTime(long time) {
10231024
return tobj.format("%Y-%m-%d %H:%M:%S");
10241025
}
10251026

1026-
protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
1027+
protected void dumpSyncState(PrintWriter pw) {
10271028
pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
10281029
pw.print("memory low: "); pw.println(mStorageIsLow);
10291030

@@ -1055,7 +1056,7 @@ protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
10551056
}
10561057

10571058
pw.print("notification info: ");
1058-
sb.setLength(0);
1059+
final StringBuilder sb = new StringBuilder();
10591060
mSyncHandler.mSyncNotificationInfo.toString(sb);
10601061
pw.println(sb.toString());
10611062

@@ -1204,7 +1205,197 @@ private void dumpDayStatistic(PrintWriter pw, SyncStorageEngine.DayStats ds) {
12041205
pw.println(")");
12051206
}
12061207

1207-
protected void dumpSyncHistory(PrintWriter pw, StringBuilder sb) {
1208+
protected void dumpSyncHistory(PrintWriter pw) {
1209+
dumpRecentHistory(pw);
1210+
dumpDayStatistics(pw);
1211+
}
1212+
1213+
private void dumpRecentHistory(PrintWriter pw) {
1214+
final ArrayList<SyncStorageEngine.SyncHistoryItem> items
1215+
= mSyncStorageEngine.getSyncHistory();
1216+
if (items != null && items.size() > 0) {
1217+
final Map<String, AuthoritySyncStats> authorityMap = Maps.newHashMap();
1218+
long totalElapsedTime = 0;
1219+
long totalTimes = 0;
1220+
final int N = items.size();
1221+
1222+
int maxAuthority = 0;
1223+
int maxAccount = 0;
1224+
for (SyncStorageEngine.SyncHistoryItem item : items) {
1225+
SyncStorageEngine.AuthorityInfo authority
1226+
= mSyncStorageEngine.getAuthority(item.authorityId);
1227+
final String authorityName;
1228+
final String accountKey;
1229+
if (authority != null) {
1230+
authorityName = authority.authority;
1231+
accountKey = authority.account.name + "/" + authority.account.type;
1232+
} else {
1233+
authorityName = "Unknown";
1234+
accountKey = "Unknown";
1235+
}
1236+
1237+
int length = authorityName.length();
1238+
if (length > maxAuthority) {
1239+
maxAuthority = length;
1240+
}
1241+
length = accountKey.length();
1242+
if (length > maxAccount) {
1243+
maxAccount = length;
1244+
}
1245+
1246+
final long elapsedTime = item.elapsedTime;
1247+
totalElapsedTime += elapsedTime;
1248+
totalTimes++;
1249+
AuthoritySyncStats authoritySyncStats = authorityMap.get(authorityName);
1250+
if (authoritySyncStats == null) {
1251+
authoritySyncStats = new AuthoritySyncStats(authorityName);
1252+
authorityMap.put(authorityName, authoritySyncStats);
1253+
}
1254+
authoritySyncStats.elapsedTime += elapsedTime;
1255+
authoritySyncStats.times++;
1256+
final Map<String, AccountSyncStats> accountMap = authoritySyncStats.accountMap;
1257+
AccountSyncStats accountSyncStats = accountMap.get(accountKey);
1258+
if (accountSyncStats == null) {
1259+
accountSyncStats = new AccountSyncStats(accountKey);
1260+
accountMap.put(accountKey, accountSyncStats);
1261+
}
1262+
accountSyncStats.elapsedTime += elapsedTime;
1263+
accountSyncStats.times++;
1264+
1265+
}
1266+
1267+
pw.println();
1268+
pw.printf("Detailed Statistics (Recent history): %d (# of times) %ds (sync time)\n",
1269+
totalTimes, totalElapsedTime / 1000);
1270+
1271+
final List<AuthoritySyncStats> sortedAuthorities =
1272+
new ArrayList<AuthoritySyncStats>(authorityMap.values());
1273+
Collections.sort(sortedAuthorities, new Comparator<AuthoritySyncStats>() {
1274+
@Override
1275+
public int compare(AuthoritySyncStats lhs, AuthoritySyncStats rhs) {
1276+
// reverse order
1277+
int compare = Integer.compare(rhs.times, lhs.times);
1278+
if (compare == 0) {
1279+
compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
1280+
}
1281+
return compare;
1282+
}
1283+
});
1284+
1285+
final int maxLength = Math.max(maxAuthority, maxAccount + 3);
1286+
final int padLength = 2 + 2 + maxLength + 2 + 10 + 11;
1287+
final char chars[] = new char[padLength];
1288+
Arrays.fill(chars, '-');
1289+
final String separator = new String(chars);
1290+
1291+
final String authorityFormat = String.format(" %%-%ds: %%-9s %%-11s\n", maxLength + 2);
1292+
final String accountFormat = String.format(" %%-%ds: %%-9s %%-11s\n", maxLength);
1293+
1294+
pw.println(separator);
1295+
for (AuthoritySyncStats authoritySyncStats : sortedAuthorities) {
1296+
String name = authoritySyncStats.name;
1297+
long elapsedTime;
1298+
int times;
1299+
String timeStr;
1300+
String timesStr;
1301+
1302+
elapsedTime = authoritySyncStats.elapsedTime;
1303+
times = authoritySyncStats.times;
1304+
timeStr = String.format("%d/%d%%",
1305+
elapsedTime / 1000,
1306+
elapsedTime * 100 / totalElapsedTime);
1307+
timesStr = String.format("%d/%d%%",
1308+
times,
1309+
times * 100 / totalTimes);
1310+
pw.printf(authorityFormat, name, timesStr, timeStr);
1311+
1312+
if (authoritySyncStats.accountMap.size() > 1) {
1313+
final List<AccountSyncStats> sortedAccounts =
1314+
new ArrayList<AccountSyncStats>(
1315+
authoritySyncStats.accountMap.values());
1316+
Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
1317+
@Override
1318+
public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
1319+
// reverse order
1320+
int compare = Integer.compare(rhs.times, lhs.times);
1321+
if (compare == 0) {
1322+
compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
1323+
}
1324+
return compare;
1325+
}
1326+
});
1327+
for (AccountSyncStats stats: sortedAccounts) {
1328+
elapsedTime = stats.elapsedTime;
1329+
times = stats.times;
1330+
timeStr = String.format("%d/%d%%",
1331+
elapsedTime / 1000,
1332+
elapsedTime * 100 / totalElapsedTime);
1333+
timesStr = String.format("%d/%d%%",
1334+
times,
1335+
times * 100 / totalTimes);
1336+
pw.printf(accountFormat, stats.name, timesStr, timeStr);
1337+
}
1338+
}
1339+
pw.println(separator);
1340+
}
1341+
1342+
pw.println();
1343+
pw.println("Recent Sync History");
1344+
final String format = " %-" + maxAccount + "s %s\n";
1345+
String lastAuthorityName = null;
1346+
String lastAccountKey = null;
1347+
long lastEventTime = 0;
1348+
for (int i = 0; i < N; i++) {
1349+
SyncStorageEngine.SyncHistoryItem item = items.get(i);
1350+
SyncStorageEngine.AuthorityInfo authority
1351+
= mSyncStorageEngine.getAuthority(item.authorityId);
1352+
final String authorityName;
1353+
final String accountKey;
1354+
if (authority != null) {
1355+
authorityName = authority.authority;
1356+
accountKey = authority.account.name + "/" + authority.account.type;
1357+
} else {
1358+
authorityName = "Unknown";
1359+
accountKey = "Unknown";
1360+
}
1361+
final long elapsedTime = item.elapsedTime;
1362+
final Time time = new Time();
1363+
final long eventTime = item.eventTime;
1364+
time.set(eventTime);
1365+
1366+
pw.printf(" #%-3d: %s %8s %5.1fs",
1367+
i + 1,
1368+
formatTime(eventTime),
1369+
SyncStorageEngine.SOURCES[item.source],
1370+
((float) elapsedTime) / 1000);
1371+
if (authorityName.equals(lastAuthorityName) && accountKey.equals(lastAccountKey)) {
1372+
final long span = (lastEventTime - eventTime) / 1000;
1373+
pw.printf(" %02d:%02d\n", span / 60, span % 60);
1374+
} else {
1375+
pw.printf(format, accountKey, authorityName);
1376+
}
1377+
1378+
lastAuthorityName = authorityName;
1379+
lastAccountKey = accountKey;
1380+
lastEventTime = eventTime;
1381+
1382+
if (item.event != SyncStorageEngine.EVENT_STOP
1383+
|| item.upstreamActivity != 0
1384+
|| item.downstreamActivity != 0) {
1385+
pw.printf(" event=%d upstreamActivity=%d downstreamActivity=%d\n",
1386+
item.event,
1387+
item.upstreamActivity,
1388+
item.downstreamActivity);
1389+
}
1390+
if (item.mesg != null
1391+
&& !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) {
1392+
pw.printf(" mesg=%s\n", item.mesg);
1393+
}
1394+
}
1395+
}
1396+
}
1397+
1398+
private void dumpDayStatistics(PrintWriter pw) {
12081399
SyncStorageEngine.DayStats dses[] = mSyncStorageEngine.getDayStatistics();
12091400
if (dses != null && dses[0] != null) {
12101401
pw.println();
@@ -1254,47 +1445,26 @@ protected void dumpSyncHistory(PrintWriter pw, StringBuilder sb) {
12541445
}
12551446
}
12561447
}
1448+
}
12571449

1258-
ArrayList<SyncStorageEngine.SyncHistoryItem> items
1259-
= mSyncStorageEngine.getSyncHistory();
1260-
if (items != null && items.size() > 0) {
1261-
pw.println();
1262-
pw.println("Recent Sync History");
1263-
final int N = items.size();
1264-
for (int i=0; i<N; i++) {
1265-
SyncStorageEngine.SyncHistoryItem item = items.get(i);
1266-
SyncStorageEngine.AuthorityInfo authority
1267-
= mSyncStorageEngine.getAuthority(item.authorityId);
1268-
pw.print(" #"); pw.print(i+1); pw.print(": ");
1269-
if (authority != null) {
1270-
pw.print(authority.account.name);
1271-
pw.print(":");
1272-
pw.print(authority.account.type);
1273-
pw.print(" ");
1274-
pw.print(authority.authority);
1275-
} else {
1276-
pw.print("<no account>");
1277-
}
1278-
Time time = new Time();
1279-
time.set(item.eventTime);
1280-
pw.print(" "); pw.print(SyncStorageEngine.SOURCES[item.source]);
1281-
pw.print(" @ ");
1282-
pw.print(formatTime(item.eventTime));
1283-
pw.print(" for ");
1284-
dumpTimeSec(pw, item.elapsedTime);
1285-
pw.println();
1286-
if (item.event != SyncStorageEngine.EVENT_STOP
1287-
|| item.upstreamActivity !=0
1288-
|| item.downstreamActivity != 0) {
1289-
pw.print(" event="); pw.print(item.event);
1290-
pw.print(" upstreamActivity="); pw.print(item.upstreamActivity);
1291-
pw.print(" downstreamActivity="); pw.println(item.downstreamActivity);
1292-
}
1293-
if (item.mesg != null
1294-
&& !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) {
1295-
pw.print(" mesg="); pw.println(item.mesg);
1296-
}
1297-
}
1450+
private static class AuthoritySyncStats {
1451+
String name;
1452+
long elapsedTime;
1453+
int times;
1454+
Map<String, AccountSyncStats> accountMap = Maps.newHashMap();
1455+
1456+
private AuthoritySyncStats(String name) {
1457+
this.name = name;
1458+
}
1459+
}
1460+
1461+
private static class AccountSyncStats {
1462+
String name;
1463+
long elapsedTime;
1464+
int times;
1465+
1466+
private AccountSyncStats(String name) {
1467+
this.name = name;
12981468
}
12991469
}
13001470

0 commit comments

Comments
 (0)