1616
1717package 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-
3319import com .android .internal .R ;
3420import com .android .internal .util .ArrayUtils ;
21+ import com .google .android .collect .Lists ;
22+ import com .google .android .collect .Maps ;
3523
3624import android .accounts .Account ;
3725import android .accounts .AccountManager ;
4230import android .app .PendingIntent ;
4331import android .content .pm .ApplicationInfo ;
4432import android .content .pm .PackageManager ;
45- import android .content .pm .ResolveInfo ;
46- import android .content .pm .RegisteredServicesCache ;
4733import android .content .pm .ProviderInfo ;
34+ import android .content .pm .RegisteredServicesCache ;
4835import android .content .pm .RegisteredServicesCacheListener ;
36+ import android .content .pm .ResolveInfo ;
4937import android .net .ConnectivityManager ;
5038import 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 ;
5150import android .os .WorkSource ;
5251import android .provider .Settings ;
5352import android .text .format .DateUtils ;
5958import java .io .FileDescriptor ;
6059import java .io .PrintWriter ;
6160import java .util .ArrayList ;
61+ import java .util .Arrays ;
6262import java .util .Collection ;
6363import java .util .Collections ;
64+ import java .util .Comparator ;
6465import java .util .HashMap ;
6566import java .util .HashSet ;
6667import java .util .Iterator ;
6768import java .util .List ;
69+ import java .util .Map ;
6870import java .util .Random ;
6971import 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