Snap for 10850711 from bfbf9082a6e19b0b0820b63ec231009916624371 to udc-qpr1-release

Change-Id: Id2f5ca2501561e4c63161fc476bdbfc101b8e62a
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 5f75117..bc9b388 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -23,6 +23,8 @@
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.FullBackupDataOutput;
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -310,6 +312,7 @@
         sDefaultValuesAddr.put(Telephony.Mms.Addr.CHARSET, CharacterSets.DEFAULT_CHARSET);
     }
 
+    private final boolean mIsDeferredRestoreServiceStarted;
 
     private SparseArray<String> mSubId2phone = new SparseArray<String>();
     private Map<String, Integer> mPhone2subId = new ArrayMap<String, Integer>();
@@ -318,6 +321,10 @@
     private ContentResolver mContentResolver;
     // How many bytes we can backup to fit into quota.
     private long mBytesOverQuota;
+    private BackupRestoreEventLogger mLogger;
+    private BackupManager mBackupManager;
+    private int mSmsCount = 0;
+    private int mMmsCount = 0;
 
     // Cache list of recipients by threadId. It reduces db requests heavily. Used during backup.
     @VisibleForTesting
@@ -326,6 +333,56 @@
     @VisibleForTesting
     Map<Set<String>, Long> mCacheGetOrCreateThreadId = null;
 
+    /**
+     * BackupRestoreEventLogger Dependencies for unit testing.
+     */
+    @VisibleForTesting
+    public interface BackupRestoreEventLoggerProxy {
+        void logItemsBackedUp(String dataType, int count);
+        void logItemsBackupFailed(String dataType, int count, String error);
+        void logItemsRestored(String dataType, int count);
+        void logItemsRestoreFailed(String dataType, int count, String error);
+    }
+
+    private BackupRestoreEventLoggerProxy mBackupRestoreEventLoggerProxy =
+            new BackupRestoreEventLoggerProxy() {
+        @Override
+        public void logItemsBackedUp(String dataType, int count) {
+            mLogger.logItemsBackedUp(dataType, count);
+        }
+
+        @Override
+        public void logItemsBackupFailed(String dataType, int count, String error) {
+            mLogger.logItemsBackupFailed(dataType, count, error);
+        }
+
+        @Override
+        public void logItemsRestored(String dataType, int count) {
+            mLogger.logItemsRestored(dataType, count);
+        }
+
+        @Override
+        public void logItemsRestoreFailed(String dataType, int count, String error) {
+            mLogger.logItemsRestoreFailed(dataType, count, error);
+        }
+    };
+
+    public TelephonyBackupAgent() {
+        mIsDeferredRestoreServiceStarted = false;
+    }
+
+    public TelephonyBackupAgent(boolean isServiceStarted) {
+        mIsDeferredRestoreServiceStarted = isServiceStarted;
+    }
+
+    /**
+     * Overrides BackupRestoreEventLogger dependencies for unit testing.
+     */
+    @VisibleForTesting
+    public void setBackupRestoreEventLoggerProxy(BackupRestoreEventLoggerProxy proxy) {
+        mBackupRestoreEventLoggerProxy = proxy;
+    }
+
     @Override
     public void onCreate() {
         super.onCreate();
@@ -342,6 +399,18 @@
                 }
             }
         }
+
+        mBackupManager = new BackupManager(getBaseContext());
+        if (mIsDeferredRestoreServiceStarted) {
+            try {
+                mLogger = mBackupManager.getDelayedRestoreLogger();
+            } catch (SecurityException e) {
+                Log.e(TAG, "onCreate" + e.toString());
+            }
+        } else {
+            mLogger = mBackupManager.getBackupRestoreEventLogger(TelephonyBackupAgent.this);
+        }
+
         mContentResolver = getContentResolver();
         initUnknownSender();
     }
@@ -350,6 +419,7 @@
     void setContentResolver(ContentResolver contentResolver) {
         mContentResolver = contentResolver;
     }
+
     @VisibleForTesting
     void setSubId(SparseArray<String> subId2Phone, Map<String, Integer> phone2subId) {
         mSubId2phone = subId2Phone;
@@ -363,6 +433,11 @@
         sDefaultValuesMms.put(Telephony.Mms.THREAD_ID, mUnknownSenderThreadId);
     }
 
+    @VisibleForTesting
+    void setBackupManager(BackupManager backupManager) {
+        mBackupManager = backupManager;
+    }
+
     @Override
     public void onFullBackup(FullBackupDataOutput data) throws IOException {
         SharedPreferences sharedPreferences = getSharedPreferences(BACKUP_PREFS, MODE_PRIVATE);
@@ -395,6 +470,8 @@
             // messages, otherwise 1000 MMS messages. Repeat until out of SMS's or MMS's.
             // It ensures backups are incremental.
             int fileNum = 0;
+            mSmsCount = 0;
+            mMmsCount = 0;
             while (smsCursor != null && !smsCursor.isAfterLast() &&
                     mmsCursor != null && !mmsCursor.isAfterLast()) {
                 final long smsDate = TimeUnit.MILLISECONDS.toSeconds(getMessageDate(smsCursor));
@@ -417,6 +494,14 @@
                 backupAll(data, mmsCursor,
                         String.format(Locale.US, MMS_BACKUP_FILE_FORMAT, fileNum++));
             }
+
+            if (mSmsCount > 0) {
+                mBackupRestoreEventLoggerProxy.logItemsBackedUp("SMS", mSmsCount);
+            }
+
+            if (mMmsCount > 0) {
+                mBackupRestoreEventLoggerProxy.logItemsBackedUp("MMS", mMmsCount);
+            }
         }
 
         mThreadArchived = new HashMap<>();
@@ -463,8 +548,10 @@
         try (JsonWriter jsonWriter = getJsonWriter(fileName)) {
             if (fileName.endsWith(SMS_BACKUP_FILE_SUFFIX)) {
                 chunk = putSmsMessagesToJson(cursor, jsonWriter);
+                mSmsCount = chunk.count;
             } else {
                 chunk = putMmsMessagesToJson(cursor, jsonWriter);
+                mMmsCount = chunk.count;
             }
         }
         backupFile(chunk, fileName, data);
@@ -610,9 +697,14 @@
             } catch (IllegalArgumentException e) {
                 // ignore
             }
-            mTelephonyBackupAgent = new TelephonyBackupAgent();
+
+            mTelephonyBackupAgent = new TelephonyBackupAgent(true);
             mTelephonyBackupAgent.attach(this);
-            mTelephonyBackupAgent.onCreate();
+            try {
+                 mTelephonyBackupAgent.onCreate();
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "onCreate" + e.toString());
+            }
 
             PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
             mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
@@ -704,6 +796,16 @@
         }
         jsonReader.endArray();
         incremenentSharedPref(true, msgCount, numExceptions);
+        if (msgCount > 0) {
+            mBackupRestoreEventLoggerProxy.logItemsRestored("SMS", msgCount);
+        }
+
+        if (numExceptions > 0) {
+            mBackupRestoreEventLoggerProxy.logItemsRestoreFailed("SMS", numExceptions,
+                    "provider_exception");
+        }
+
+        reportDelayedRestoreResult();
     }
 
     void incremenentSharedPref(boolean sms, int msgCount, int numExceptions) {
@@ -768,6 +870,16 @@
         }
         Log.d(TAG, "putMmsMessagesToProvider handled " + total + " new messages.");
         incremenentSharedPref(false, total, numExceptions);
+        if (total > 0) {
+            mBackupRestoreEventLoggerProxy.logItemsRestored("MMS", total);
+        }
+
+        if (numExceptions > 0) {
+            mBackupRestoreEventLoggerProxy.logItemsRestoreFailed("MMS", numExceptions,
+                    "provider_exception");
+        }
+
+        reportDelayedRestoreResult();
     }
 
     private void notifyBulkMmsChange() {
@@ -776,6 +888,16 @@
         ProviderUtil.notifyIfNotDefaultSmsApp(Telephony.Mms.CONTENT_URI, null, this);
     }
 
+    private void reportDelayedRestoreResult() {
+        if (mIsDeferredRestoreServiceStarted) {
+            try {
+                mBackupManager.reportDelayedRestoreResult(mLogger);
+            } catch (SecurityException e) {
+                Log.e(TAG, "putMmsMessagesToProvider" + e.toString());
+            }
+        }
+    }
+
     @VisibleForTesting
     static final String[] PROJECTION_ID = {BaseColumns._ID};
     private static final int ID_IDX = 0;
diff --git a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
index bf0f49b..f75480a 100644
--- a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertArrayEquals;
 
 import android.annotation.TargetApi;
+import android.app.backup.BackupManager;
 import android.app.backup.FullBackupDataOutput;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -52,6 +53,7 @@
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.mockito.Mockito;
 
 import java.io.File;
 import java.io.IOException;
@@ -111,6 +113,34 @@
 
     TelephonyBackupAgent mTelephonyBackupAgent;
 
+    private boolean mItemBackedUp = false;
+    private boolean mItemBackedUpFailed = false;
+    private boolean mItemRestored = false;
+    private boolean mItemsRestoreFailed = false;
+
+    private TelephonyBackupAgent.BackupRestoreEventLoggerProxy mBackupRestoreEventLoggerProxy =
+            new TelephonyBackupAgent.BackupRestoreEventLoggerProxy() {
+        @Override
+        public void logItemsBackedUp(String dataType, int count) {
+            mItemBackedUp = true;
+        }
+
+        @Override
+        public void logItemsBackupFailed(String dataType, int count, String error) {
+            mItemBackedUpFailed = true;
+        }
+
+        @Override
+        public void logItemsRestored(String dataType, int count) {
+            mItemRestored = true;
+        }
+
+        @Override
+        public void logItemsRestoreFailed(String dataType, int count, String error) {
+            mItemsRestoreFailed = true;
+        }
+    };
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -317,12 +347,22 @@
         mTelephonyBackupAgent.clearSharedPreferences();
         mTelephonyBackupAgent.setContentResolver(mMockContentResolver);
         mTelephonyBackupAgent.setSubId(mSubId2Phone, mPhone2SubId);
+
+        mItemBackedUp = false;
+        mItemBackedUpFailed = false;
+        mItemRestored = false;
+        mItemsRestoreFailed = false;
+        BackupManager mockBackupManager = Mockito.mock(BackupManager.class);
+        mTelephonyBackupAgent.setBackupRestoreEventLoggerProxy(mBackupRestoreEventLoggerProxy);
+        mTelephonyBackupAgent.setBackupManager(mockBackupManager);
     }
 
     @Override
     protected void tearDown() throws Exception {
         mTelephonyBackupAgent.clearSharedPreferences();
         super.tearDown();
+        mTelephonyBackupAgent.setBackupRestoreEventLoggerProxy(null);
+        mTelephonyBackupAgent.setBackupManager(null);
     }
 
     private static String makeJsonArray(String[] json) {
@@ -479,6 +519,7 @@
     public void testBackupSms_NoSms() throws Exception {
         mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
         assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString());
+        assertFalse(mItemBackedUp);
     }
 
     /**
@@ -534,6 +575,7 @@
     public void testBackupMms_NoMms() throws Exception {
         mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
         assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString());
+        assertFalse(mItemBackedUp);
     }
 
     /**
@@ -666,6 +708,7 @@
                 }
         );
         assertEquals(0, mmsProvider.getRowsAdded());
+        assertFalse(mItemRestored);
     }
 
     /**
@@ -710,6 +753,7 @@
                 }
         );
         assertEquals(7, mmsProvider.getRowsAdded());
+        assertTrue(mItemRestored);
     }
 
     public void testRestoreMmsWithNullBody() throws Exception {
@@ -730,6 +774,7 @@
         );
 
         assertEquals(3, mmsProvider.getRowsAdded());
+        assertTrue(mItemRestored);
     }
 
     /**
@@ -750,17 +795,23 @@
         FullBackupDataOutput fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSize, fullBackupDataOutput.getSize());
+        assertTrue(mItemBackedUp);
+        mItemBackedUp = false;
 
         mTelephonyBackupAgent.onQuotaExceeded(backupSize, backupSize - 100);
         fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSizeAfterFirstQuotaHit, fullBackupDataOutput.getSize());
+        assertTrue(mItemBackedUp);
+        mItemBackedUp = false;
 
         mTelephonyBackupAgent.onQuotaExceeded(backupSizeAfterFirstQuotaHit,
                 backupSizeAfterFirstQuotaHit - 200);
         fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSizeAfterSecondQuotaHit, fullBackupDataOutput.getSize());
+        assertTrue(mItemBackedUp);
+        mItemBackedUp = false;
     }
 
     /**