Add sync reason to dumpsys

Also:
 * add a second history section that logs
 * log mesg as text instead of number
 * dump Sync Status as a table

 Sample log:
Recent Sync History
  #1  : 2012-10-11 15:06:11     USER    0.4s            aagmtest1@gmail.com/com.google u0  com.android.calendar                                  com.google.android.calendar
  #2  : 2012-10-11 15:06:11     USER    0.1s            aagmtest1@gmail.com/com.google u0  subscribedfeeds                                       android.uid.system:1000
    mesg=parse-error
  #3  : 2012-10-11 15:06:11     USER    0.0s            aagmtest1@gmail.com/com.google u0  com.google.android.apps.uploader.PicasaUploadProvider android.uid.system:1000
  #4  : 2012-10-11 15:06:10     USER    0.1s            aagmtest1@gmail.com/com.google u0  com.google.android.gms.plus.action                    android.uid.system:1000

Recent Sync History Extras
  #1  : 2012-10-11 15:06:11     USER   aagmtest1@gmail.com/com.google u0  com.android.calendar                                  Bundle[{feed=aagmtest1@gmail.com, force=true, ignore_settings=true, ignore_backoff=true}]
  #2  : 2012-10-11 15:06:11     USER   aagmtest1@gmail.com/com.google u0  subscribedfeeds                                       Bundle[{ignore_backoff=true, force=true, ignore_settings=true}]
  #3  : 2012-10-11 15:06:11     USER   aagmtest1@gmail.com/com.google u0  com.google.android.apps.uploader.PicasaUploadProvider Bundle[{ignore_backoff=true, force=true, ignore_settings=true}]
  #4  : 2012-10-11 15:06:10     USER   aagmtest1@gmail.com/com.google u0  com.google.android.gms.plus.action                    Bundle[{ignore_backoff=true, force=true, ignore_settings=true}]

Sync Status
Account aagmtest1@gmail.com u0 com.google
=======================================================================
Authority                                           Syncable  Enabled  Delay  Loc  Poll  Per  Serv  User  Tot  Time  Last Sync            Periodic
-------------------------------------------------------------------------------------------------------------------------------------------------------------
com.google.android.apps.currents                    1         true            0    2     1    2     1     6    0:35  PERIODIC SUCCESS     86400
                                                                                                                     2012-10-12 14:59:40  2012-10-13 14:58:13
com.google.android.music.MusicContent               1         true            0    0     1    2     1     4    0:09  PERIODIC SUCCESS     86400
                                                                                                                     2012-10-12 14:59:18  2012-10-13 14:58:13
com.google.android.gms.plus.action                  1         true            0    0     1    1     1     3    0:00  PERIODIC SUCCESS     86400
                                                                                                                     2012-10-12 14:59:15  2012-10-13 14:58:13
com.google.android.apps.magazines                   1         true            0    1     1    2     1     5    0:14  PERIODIC SUCCESS     86400
                                                                                                                     2012-10-12 14:59:00  2012-10-13 14:58:13

Change-Id: Iffeb825e4b4f6217940a39b0dd71e06856f08f3f
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 10e7bff..be1e796 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -25,7 +25,6 @@
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
-import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -145,6 +144,7 @@
     public static class PendingOperation {
         final Account account;
         final int userId;
+        final int reason;
         final int syncSource;
         final String authority;
         final Bundle extras;        // note: read-only.
@@ -153,11 +153,12 @@
         int authorityId;
         byte[] flatExtras;
 
-        PendingOperation(Account account, int userId, int source,
+        PendingOperation(Account account, int userId, int reason,int source,
                 String authority, Bundle extras, boolean expedited) {
             this.account = account;
             this.userId = userId;
             this.syncSource = source;
+            this.reason = reason;
             this.authority = authority;
             this.extras = extras != null ? new Bundle(extras) : extras;
             this.expedited = expedited;
@@ -167,6 +168,7 @@
         PendingOperation(PendingOperation other) {
             this.account = other.account;
             this.userId = other.userId;
+            this.reason = other.reason;
             this.syncSource = other.syncSource;
             this.authority = other.authority;
             this.extras = other.extras;
@@ -245,6 +247,8 @@
         long downstreamActivity;
         String mesg;
         boolean initialization;
+        Bundle extras;
+        int reason;
     }
 
     public static class DayStats {
@@ -264,10 +268,12 @@
          * Called when a sync is needed on an account(s) due to some change in state.
          * @param account
          * @param userId
+         * @param reason
          * @param authority
          * @param extras
          */
-        public void onSyncRequest(Account account, int userId, String authority, Bundle extras);
+        public void onSyncRequest(Account account, int userId, int reason, String authority,
+                Bundle extras);
     }
 
     // Primary list of all syncable authorities.  Also our global lock.
@@ -497,7 +503,8 @@
         }
 
         if (sync) {
-            requestSync(account, userId, providerName, new Bundle());
+            requestSync(account, userId, SyncOperation.REASON_SYNC_AUTO, providerName,
+                    new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
@@ -545,7 +552,8 @@
         }
 
         if (syncable > 0) {
-            requestSync(account, userId, providerName, new Bundle());
+            requestSync(account, userId, SyncOperation.REASON_IS_SYNCABLE,  providerName,
+                    new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
@@ -778,7 +786,8 @@
             writeAccountInfoLocked();
         }
         if (flag) {
-            requestSync(null, userId, null, new Bundle());
+            requestSync(null, userId, SyncOperation.REASON_MASTER_SYNC_AUTO, null,
+                    new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT);
@@ -1041,8 +1050,8 @@
     /**
      * Note that sync has started for the given account and authority.
      */
-    public long insertStartSyncEvent(Account accountName, int userId, String authorityName,
-                                     long now, int source, boolean initialization) {
+    public long insertStartSyncEvent(Account accountName, int userId, int reason,
+            String authorityName, long now, int source, boolean initialization, Bundle extras) {
         long id;
         synchronized (mAuthorities) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -1061,6 +1070,8 @@
             if (mNextHistoryId < 0) mNextHistoryId = 0;
             item.eventTime = now;
             item.source = source;
+            item.reason = reason;
+            item.extras = extras;
             item.event = EVENT_START;
             mSyncHistory.add(0, item);
             while (mSyncHistory.size() > MAX_HISTORY) {
@@ -2036,7 +2047,7 @@
         }
     }
 
-    public static final int PENDING_OPERATION_VERSION = 2;
+    public static final int PENDING_OPERATION_VERSION = 3;
 
     /**
      * Read all pending operations back in to the initial engine state.
@@ -2065,6 +2076,7 @@
                 } else {
                     expedited = false;
                 }
+                int reason = in.readInt();
                 AuthorityInfo authority = mAuthorities.get(authorityId);
                 if (authority != null) {
                     Bundle extras;
@@ -2076,13 +2088,14 @@
                         extras = new Bundle();
                     }
                     PendingOperation op = new PendingOperation(
-                            authority.account, authority.userId, syncSource,
+                            authority.account, authority.userId, reason, syncSource,
                             authority.authority, extras, expedited);
                     op.authorityId = authorityId;
                     op.flatExtras = flatExtras;
                     if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account
                             + " auth=" + op.authority
                             + " src=" + op.syncSource
+                            + " reason=" + op.reason
                             + " expedited=" + op.expedited
                             + " extras=" + op.extras);
                     mPendingOperations.add(op);
@@ -2102,6 +2115,7 @@
         }
         out.writeByteArray(op.flatExtras);
         out.writeInt(op.expedited ? 1 : 0);
+        out.writeInt(op.reason);
     }
 
     /**
@@ -2196,14 +2210,15 @@
         return bundle;
     }
 
-    private void requestSync(Account account, int userId, String authority, Bundle extras) {
+    private void requestSync(Account account, int userId, int reason, String authority,
+            Bundle extras) {
         // If this is happening in the system process, then call the syncrequest listener
         // to make a request back to the SyncManager directly.
         // If this is probably a test instance, then call back through the ContentResolver
         // which will know which userId to apply based on the Binder id.
         if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
                 && mSyncRequestListener != null) {
-            mSyncRequestListener.onSyncRequest(account, userId, authority, extras);
+            mSyncRequestListener.onSyncRequest(account, userId, reason, authority, extras);
         } else {
             ContentResolver.requestSync(account, authority, extras);
         }