Merge changes If0e0f2d8,Iedf391e2,I8a7319a9 into main

* changes:
  Add Backup & Restore Metrics for Network Policies settings.
  Add Backup & Restore Metrics for SoftAP settings.
  Add Backup & Restore Metrics for lock settings.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index a2cc008..ef0bc3b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -193,6 +193,7 @@
             "power_button_instantly_locks";
     private static final String KEY_LOCK_SETTINGS_PIN_ENHANCED_PRIVACY =
             "pin_enhanced_privacy";
+    private static final int NUM_LOCK_SETTINGS = 5;
 
     // Error messages for logging metrics.
     private static final String ERROR_COULD_NOT_READ_FROM_CURSOR =
@@ -208,6 +209,13 @@
     private static final String ERROR_SKIPPED_DUE_TO_LARGE_SCREEN =
         "skipped_due_to_large_screen";
     private static final String ERROR_DID_NOT_PASS_VALIDATION = "did_not_pass_validation";
+    private static final String ERROR_IO_EXCEPTION = "io_exception";
+    private static final String ERROR_FAILED_TO_RESTORE_SOFTAP_CONFIG =
+        "failed_to_restore_softap_config";
+    private static final String ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES =
+        "failed_to_convert_network_policies";
+    private static final String ERROR_UNKNOWN_BACKUP_SERIALIZATION_VERSION =
+        "unknown_backup_serialization_version";
 
 
     // Name of the temporary file we use during full backup/restore.  This is
@@ -794,29 +802,44 @@
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(baos);
+        int backedUpSettingsCount = 0;
         try {
             out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED);
             out.writeUTF(ownerInfoEnabled ? "1" : "0");
+            backedUpSettingsCount++;
             if (ownerInfo != null) {
                 out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO);
                 out.writeUTF(ownerInfo != null ? ownerInfo : "");
+                backedUpSettingsCount++;
             }
             if (lockPatternUtils.isVisiblePatternEverChosen(userId)) {
                 out.writeUTF(KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED);
                 out.writeUTF(visiblePatternEnabled ? "1" : "0");
+                backedUpSettingsCount++;
             }
             if (lockPatternUtils.isPowerButtonInstantlyLocksEverChosen(userId)) {
                 out.writeUTF(KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS);
                 out.writeUTF(powerButtonInstantlyLocks ? "1" : "0");
+                backedUpSettingsCount++;
             }
             if (lockPatternUtils.isPinEnhancedPrivacyEverChosen(userId)) {
                 out.writeUTF(KEY_LOCK_SETTINGS_PIN_ENHANCED_PRIVACY);
                 out.writeUTF(lockPatternUtils.isPinEnhancedPrivacyEnabled(userId) ? "1" : "0");
+                backedUpSettingsCount++;
             }
             // End marker
             out.writeUTF("");
             out.flush();
+            if (areAgentMetricsEnabled) {
+                numberOfSettingsPerKey.put(KEY_LOCK_SETTINGS, backedUpSettingsCount);
+            }
         } catch (IOException ioe) {
+            if (areAgentMetricsEnabled) {
+                mBackupRestoreEventLogger.logItemsBackupFailed(
+                    KEY_LOCK_SETTINGS,
+                    NUM_LOCK_SETTINGS - backedUpSettingsCount,
+                    ERROR_IO_EXCEPTION);
+            }
         }
         return baos.toByteArray();
     }
@@ -1162,6 +1185,7 @@
 
         ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, nBytes);
         DataInputStream in = new DataInputStream(bais);
+        int restoredLockSettingsCount = 0;
         try {
             String key;
             // Read until empty string marker
@@ -1187,9 +1211,20 @@
                         lockPatternUtils.setPinEnhancedPrivacyEnabled("1".equals(value), userId);
                         break;
                 }
+                if (areAgentMetricsEnabled) {
+                    mBackupRestoreEventLogger.logItemsRestored(KEY_LOCK_SETTINGS, /* count= */ 1);
+                    restoredLockSettingsCount++;
+                }
+
             }
             in.close();
         } catch (IOException ioe) {
+            if (areAgentMetricsEnabled) {
+                mBackupRestoreEventLogger.logItemsRestoreFailed(
+                        KEY_LOCK_SETTINGS,
+                        NUM_LOCK_SETTINGS - restoredLockSettingsCount,
+                        ERROR_IO_EXCEPTION);
+            }
         }
     }
 
@@ -1309,12 +1344,31 @@
         mWifiManager.restoreSupplicantBackupData(supplicant_bytes, ipconfig_bytes);
     }
 
-    private byte[] getSoftAPConfiguration() {
-        return mWifiManager.retrieveSoftApBackupData();
+    @VisibleForTesting
+    byte[] getSoftAPConfiguration() {
+        byte[] data = mWifiManager.retrieveSoftApBackupData();
+        if (areAgentMetricsEnabled) {
+            // We're unable to determine how many settings this includes, so we'll just log 1.
+            numberOfSettingsPerKey.put(KEY_SOFTAP_CONFIG, 1);
+        }
+        return data;
     }
 
-    private void restoreSoftApConfiguration(byte[] data) {
-        SoftApConfiguration configInCloud = mWifiManager.restoreSoftApBackupData(data);
+    @VisibleForTesting
+    void restoreSoftApConfiguration(byte[] data) {
+        SoftApConfiguration configInCloud;
+        if (areAgentMetricsEnabled) {
+            try {
+                configInCloud = mWifiManager.restoreSoftApBackupData(data);
+                mBackupRestoreEventLogger.logItemsRestored(KEY_SOFTAP_CONFIG, /* count= */ 1);
+            } catch (Exception e) {
+                configInCloud = null;
+                mBackupRestoreEventLogger.logItemsRestoreFailed(
+                    KEY_SOFTAP_CONFIG, /* count= */ 1, ERROR_FAILED_TO_RESTORE_SOFTAP_CONFIG);
+            }
+        } else {
+            configInCloud = mWifiManager.restoreSoftApBackupData(data);
+        }
         if (configInCloud != null) {
             if (DEBUG) Log.d(TAG, "Successfully unMarshaled SoftApConfiguration ");
             // Depending on device hardware, we may need to notify the user of a setting change
@@ -1384,6 +1438,7 @@
             try {
                 out.writeInt(NETWORK_POLICIES_BACKUP_VERSION);
                 out.writeInt(policies.length);
+                int numberOfPoliciesBackedUp = 0;
                 for (NetworkPolicy policy : policies) {
                     // We purposefully only backup policies that the user has
                     // defined; any inferred policies might include
@@ -1393,13 +1448,23 @@
                         out.writeByte(BackupUtils.NOT_NULL);
                         out.writeInt(marshaledPolicy.length);
                         out.write(marshaledPolicy);
+                        if (areAgentMetricsEnabled) {
+                            numberOfPoliciesBackedUp++;
+                        }
                     } else {
                         out.writeByte(BackupUtils.NULL);
                     }
                 }
+                if (areAgentMetricsEnabled) {
+                    numberOfSettingsPerKey.put(KEY_NETWORK_POLICIES, numberOfPoliciesBackedUp);
+                }
             } catch (IOException ioe) {
                 Log.e(TAG, "Failed to convert NetworkPolicies to byte array " + ioe.getMessage());
                 baos.reset();
+                mBackupRestoreEventLogger.logItemsBackupFailed(
+                    KEY_NETWORK_POLICIES,
+                    policies.length,
+                    ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES);
             }
         }
         return baos.toByteArray();
@@ -1433,6 +1498,10 @@
             try {
                 int version = in.readInt();
                 if (version < 1 || version > NETWORK_POLICIES_BACKUP_VERSION) {
+                    mBackupRestoreEventLogger.logItemsRestoreFailed(
+                            KEY_NETWORK_POLICIES,
+                            /* count= */ 1,
+                            ERROR_UNKNOWN_BACKUP_SERIALIZATION_VERSION);
                     throw new BackupUtils.BadVersionException(
                             "Unknown Backup Serialization Version");
                 }
@@ -1449,10 +1518,15 @@
                 }
                 // Only set the policies if there was no error in the restore operation
                 networkPolicyManager.setNetworkPolicies(policies);
+                mBackupRestoreEventLogger.logItemsRestored(KEY_NETWORK_POLICIES, policies.length);
             } catch (NullPointerException | IOException | BackupUtils.BadVersionException
                     | DateTimeException e) {
                 // NPE can be thrown when trying to instantiate a NetworkPolicy
                 Log.e(TAG, "Failed to convert byte array to NetworkPolicies " + e.getMessage());
+                mBackupRestoreEventLogger.logItemsRestoreFailed(
+                        KEY_NETWORK_POLICIES,
+                        /* count= */ 1,
+                        ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES);
             }
         }
     }
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 18c43a7..95dd0db 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -16,6 +16,8 @@
 
 package com.android.providers.settings;
 
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
@@ -28,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
+import android.annotation.Nullable;
 import android.app.backup.BackupAnnotations.BackupDestination;
 import android.app.backup.BackupAnnotations.OperationType;
 import android.app.backup.BackupDataInput;
@@ -42,6 +45,8 @@
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
+import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -126,6 +131,7 @@
 
     @Mock private BackupDataInput mBackupDataInput;
     @Mock private BackupDataOutput mBackupDataOutput;
+    @Mock private static WifiManager mWifiManager;
 
     private TestFriendlySettingsBackupAgent mAgentUnderTest;
     private Context mContext;
@@ -754,6 +760,80 @@
         assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
     }
 
+    @Test
+    @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+    public void getSoftAPConfiguration_flagIsEnabled_numberOfSettingsInKeyAreRecorded() {
+        mAgentUnderTest.onCreate(
+            UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.BACKUP);
+        when(mWifiManager.retrieveSoftApBackupData()).thenReturn(null);
+
+        mAgentUnderTest.getSoftAPConfiguration();
+
+        assertEquals(mAgentUnderTest.getNumberOfSettingsPerKey(KEY_SOFTAP_CONFIG), 1);
+    }
+
+    @Test
+    @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+    public void getSoftAPConfiguration_flagIsNotEnabled_numberOfSettingsInKeyAreNotRecorded() {
+        mAgentUnderTest.onCreate(
+            UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.BACKUP);
+        when(mWifiManager.retrieveSoftApBackupData()).thenReturn(null);
+
+        mAgentUnderTest.getSoftAPConfiguration();
+
+        assertEquals(mAgentUnderTest.getNumberOfSettingsPerKey(KEY_SOFTAP_CONFIG), 0);
+    }
+
+    @Test
+    @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+    public void
+        restoreSoftApConfiguration_flagIsEnabled_restoreIsSuccessful_successMetricsAreLogged() {
+        mAgentUnderTest.onCreate(
+            UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+        SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid("test").build();
+        byte[] data = config.toString().getBytes();
+        when(mWifiManager.restoreSoftApBackupData(any())).thenReturn(null);
+
+        mAgentUnderTest.restoreSoftApConfiguration(data);
+
+        DataTypeResult loggingResult =
+            getLoggingResultForDatatype(KEY_SOFTAP_CONFIG, mAgentUnderTest);
+        assertNotNull(loggingResult);
+        assertEquals(loggingResult.getSuccessCount(), 1);
+    }
+
+    @Test
+    @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+    public void
+        restoreSoftApConfiguration_flagIsEnabled_restoreIsNotSuccessful_failureMetricsAreLogged() {
+        mAgentUnderTest.onCreate(
+            UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+        SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid("test").build();
+        byte[] data = config.toString().getBytes();
+        when(mWifiManager.restoreSoftApBackupData(any())).thenThrow(new RuntimeException());
+
+        mAgentUnderTest.restoreSoftApConfiguration(data);
+
+        DataTypeResult loggingResult =
+            getLoggingResultForDatatype(KEY_SOFTAP_CONFIG, mAgentUnderTest);
+        assertNotNull(loggingResult);
+        assertEquals(loggingResult.getFailCount(), 1);
+    }
+
+    @Test
+    @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+    public void restoreSoftApConfiguration_flagIsNotEnabled_metricsAreNotLogged() {
+        mAgentUnderTest.onCreate(
+            UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+        SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid("test").build();
+        byte[] data = config.toString().getBytes();
+        when(mWifiManager.restoreSoftApBackupData(any())).thenReturn(null);
+
+        mAgentUnderTest.restoreSoftApConfiguration(data);
+
+        assertNull(getLoggingResultForDatatype(KEY_SOFTAP_CONFIG, mAgentUnderTest));
+    }
+
     private byte[] generateBackupData(Map<String, String> keyValueData) {
         int totalBytes = 0;
         for (String key : keyValueData.keySet()) {
@@ -890,6 +970,13 @@
                 this.numberOfSettingsPerKey.put(key, numberOfSettings);
             }
         }
+
+        int getNumberOfSettingsPerKey(String key) {
+            if (numberOfSettingsPerKey == null || !numberOfSettingsPerKey.containsKey(key)) {
+                return 0;
+            }
+            return numberOfSettingsPerKey.get(key);
+        }
     }
 
     /** The TestSettingsHelper tracks which values have been backed up and/or restored. */
@@ -944,6 +1031,14 @@
         public ContentResolver getContentResolver() {
             return mContentResolver;
         }
+
+        @Override
+        public Object getSystemService(String name) {
+            if (name.equals(Context.WIFI_SERVICE)) {
+                return mWifiManager;
+            }
+            return super.getSystemService(name);
+        }
     }
 
     /** ContentProvider which returns a set of known test values. */