Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +3 −113 Original line number Diff line number Diff line Loading @@ -18,10 +18,13 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; import android.aconfig.Aconfig.flag_permission; import android.aconfig.Aconfig.flag_state; import android.aconfig.Aconfig.parsed_flag; import android.aconfig.Aconfig.parsed_flags; import android.aconfigd.AconfigdFlagInfo; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -65,14 +68,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; Loading @@ -84,18 +83,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; // FOR ACONFIGD TEST MISSION AND ROLLOUT import java.io.DataInputStream; import java.io.DataOutputStream; import android.util.proto.ProtoInputStream; import android.aconfigd.Aconfigd.StorageRequestMessage; import android.aconfigd.Aconfigd.StorageRequestMessages; import android.aconfigd.Aconfigd.StorageReturnMessage; import android.aconfigd.Aconfigd.StorageReturnMessages; import android.aconfigd.AconfigdClientSocket; import android.aconfigd.AconfigdFlagInfo; import android.aconfigd.AconfigdJavaUtils; import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; /** * This class contains the state for one type of settings. It is responsible * for saving the state asynchronously to an XML file after a mutation and Loading Loading @@ -393,22 +380,6 @@ final class SettingsState { getAllAconfigFlagsFromSettings(mAconfigDefaultFlags); } } if (isConfigSettingsKey(mKey)) { requests = handleBulkSyncToNewStorage(mAconfigDefaultFlags); } } if (enableAconfigStorageDaemon()) { if (isConfigSettingsKey(mKey)){ AconfigdClientSocket localSocket = AconfigdJavaUtils.getAconfigdClientSocket(); if (requests != null) { InputStream res = localSocket.send(requests.getBytes()); if (res == null) { Slog.w(LOG_TAG, "Bulk sync request to acongid failed."); } } } } } Loading Loading @@ -482,87 +453,6 @@ final class SettingsState { return flag; } // TODO(b/341764371): migrate aconfig flag push to GMS core @VisibleForTesting @GuardedBy("mLock") public ProtoOutputStream handleBulkSyncToNewStorage( Map<String, AconfigdFlagInfo> aconfigFlagMap) { // get marker or add marker if it does not exist Setting markerSetting = mSettings.get(BULK_SYNC_MARKER); int localCounter = 0; if (markerSetting == null) { markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig"); mSettings.put(BULK_SYNC_MARKER, markerSetting); } try { localCounter = Integer.parseInt(markerSetting.value); } catch (NumberFormatException e) { // reset local counter markerSetting.value = "0"; } if (enableAconfigStorageDaemon()) { Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER); int serverCounter = 0; if (bulkSyncCounter != null) { try { serverCounter = Integer.parseInt(bulkSyncCounter.value); } catch (NumberFormatException e) { // reset the local value of server counter bulkSyncCounter.value = "0"; } } boolean shouldSync = localCounter < serverCounter; if (!shouldSync) { // CASE 1, flag is on, bulk sync marker true, nothing to do return null; } else { // CASE 2, flag is on, bulk sync marker false. Do following two tasks // (1) Do bulk sync here. // (2) After bulk sync, set marker to true. // first add storage reset request ProtoOutputStream requests = new ProtoOutputStream(); AconfigdJavaUtils.writeResetStorageRequest(requests); // loop over all settings and add flag override requests for (AconfigdFlagInfo flag : aconfigFlagMap.values()) { // don't sync read_only flags if (!flag.getIsReadWrite()) { continue; } if (flag.getHasServerOverride()) { AconfigdJavaUtils.writeFlagOverrideRequest( requests, flag.getPackageName(), flag.getFlagName(), flag.getServerFlagValue(), StorageRequestMessage.SERVER_ON_REBOOT); } if (flag.getHasLocalOverride()) { AconfigdJavaUtils.writeFlagOverrideRequest( requests, flag.getPackageName(), flag.getFlagName(), flag.getLocalFlagValue(), StorageRequestMessage.LOCAL_ON_REBOOT); } } // mark sync has been done markerSetting.value = String.valueOf(serverCounter); scheduleWriteIfNeededLocked(); return requests; } } else { return null; } } @GuardedBy("mLock") private void loadAconfigDefaultValuesLocked(List<String> filePaths) { for (String fileName : filePaths) { Loading packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +6 −128 Original line number Diff line number Diff line Loading @@ -30,19 +30,20 @@ import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Xml; import android.util.proto.ProtoOutputStream; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.TypedXmlSerializer; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.DisableFlags; import android.platform.test.flag.junit.SetFlagsRule; import com.google.common.base.Strings; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; Loading @@ -51,11 +52,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class SettingsStateTest { Loading Loading @@ -1084,124 +1080,6 @@ public class SettingsStateTest { assertTrue(flag1.getHasLocalOverride()); } @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Test @EnableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) public void testHandleBulkSyncWithAconfigdEnabled() { int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); Object lock = new Object(); SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey, SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); Map<String, AconfigdFlagInfo> flags = new HashMap<>(); flags.put( "com.android.flags/flag1", AconfigdFlagInfo.newBuilder() .setPackageName("com.android.flags") .setFlagName("flag1") .setBootFlagValue("true") .setIsReadWrite(true) .build()); flags.put( "com.android.flags/flag2", AconfigdFlagInfo.newBuilder() .setPackageName("com.android.flags") .setFlagName("flag2") .setBootFlagValue("true") .setIsReadWrite(false) .build()); String bulkSyncMarker = "aconfigd_marker/bulk_synced"; String bulkSyncCounter = "core_experiments_team_internal/" + "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; synchronized (lock) { settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); // first bulk sync ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); assertTrue(requests != null); String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); // send time should no longer bulk sync requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); // won't sync if the marker is string settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // won't sync if the marker and counter value are the same settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); } } @Test @DisableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) public void testHandleBulkSyncWithAconfigdDisabled() { int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); Object lock = new Object(); SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey, SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); Map<String, AconfigdFlagInfo> flags = new HashMap<>(); String bulkSyncMarker = "aconfigd_marker/bulk_synced"; String bulkSyncCounter = "core_experiments_team_internal/" + "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; synchronized (lock) { settingsState.insertSettingLocked("aconfigd_marker/bulk_synced", "true", null, false, "aconfig"); // when aconfigd is off, should change the marker to false ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // marker started with false value, after call, it should remain false requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // won't sync settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); } } @Test public void testGetAllAconfigFlagsFromSettings() throws Exception { final Object lock = new Object(); Loading Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +3 −113 Original line number Diff line number Diff line Loading @@ -18,10 +18,13 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; import android.aconfig.Aconfig.flag_permission; import android.aconfig.Aconfig.flag_state; import android.aconfig.Aconfig.parsed_flag; import android.aconfig.Aconfig.parsed_flags; import android.aconfigd.AconfigdFlagInfo; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -65,14 +68,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; Loading @@ -84,18 +83,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; // FOR ACONFIGD TEST MISSION AND ROLLOUT import java.io.DataInputStream; import java.io.DataOutputStream; import android.util.proto.ProtoInputStream; import android.aconfigd.Aconfigd.StorageRequestMessage; import android.aconfigd.Aconfigd.StorageRequestMessages; import android.aconfigd.Aconfigd.StorageReturnMessage; import android.aconfigd.Aconfigd.StorageReturnMessages; import android.aconfigd.AconfigdClientSocket; import android.aconfigd.AconfigdFlagInfo; import android.aconfigd.AconfigdJavaUtils; import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; /** * This class contains the state for one type of settings. It is responsible * for saving the state asynchronously to an XML file after a mutation and Loading Loading @@ -393,22 +380,6 @@ final class SettingsState { getAllAconfigFlagsFromSettings(mAconfigDefaultFlags); } } if (isConfigSettingsKey(mKey)) { requests = handleBulkSyncToNewStorage(mAconfigDefaultFlags); } } if (enableAconfigStorageDaemon()) { if (isConfigSettingsKey(mKey)){ AconfigdClientSocket localSocket = AconfigdJavaUtils.getAconfigdClientSocket(); if (requests != null) { InputStream res = localSocket.send(requests.getBytes()); if (res == null) { Slog.w(LOG_TAG, "Bulk sync request to acongid failed."); } } } } } Loading Loading @@ -482,87 +453,6 @@ final class SettingsState { return flag; } // TODO(b/341764371): migrate aconfig flag push to GMS core @VisibleForTesting @GuardedBy("mLock") public ProtoOutputStream handleBulkSyncToNewStorage( Map<String, AconfigdFlagInfo> aconfigFlagMap) { // get marker or add marker if it does not exist Setting markerSetting = mSettings.get(BULK_SYNC_MARKER); int localCounter = 0; if (markerSetting == null) { markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig"); mSettings.put(BULK_SYNC_MARKER, markerSetting); } try { localCounter = Integer.parseInt(markerSetting.value); } catch (NumberFormatException e) { // reset local counter markerSetting.value = "0"; } if (enableAconfigStorageDaemon()) { Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER); int serverCounter = 0; if (bulkSyncCounter != null) { try { serverCounter = Integer.parseInt(bulkSyncCounter.value); } catch (NumberFormatException e) { // reset the local value of server counter bulkSyncCounter.value = "0"; } } boolean shouldSync = localCounter < serverCounter; if (!shouldSync) { // CASE 1, flag is on, bulk sync marker true, nothing to do return null; } else { // CASE 2, flag is on, bulk sync marker false. Do following two tasks // (1) Do bulk sync here. // (2) After bulk sync, set marker to true. // first add storage reset request ProtoOutputStream requests = new ProtoOutputStream(); AconfigdJavaUtils.writeResetStorageRequest(requests); // loop over all settings and add flag override requests for (AconfigdFlagInfo flag : aconfigFlagMap.values()) { // don't sync read_only flags if (!flag.getIsReadWrite()) { continue; } if (flag.getHasServerOverride()) { AconfigdJavaUtils.writeFlagOverrideRequest( requests, flag.getPackageName(), flag.getFlagName(), flag.getServerFlagValue(), StorageRequestMessage.SERVER_ON_REBOOT); } if (flag.getHasLocalOverride()) { AconfigdJavaUtils.writeFlagOverrideRequest( requests, flag.getPackageName(), flag.getFlagName(), flag.getLocalFlagValue(), StorageRequestMessage.LOCAL_ON_REBOOT); } } // mark sync has been done markerSetting.value = String.valueOf(serverCounter); scheduleWriteIfNeededLocked(); return requests; } } else { return null; } } @GuardedBy("mLock") private void loadAconfigDefaultValuesLocked(List<String> filePaths) { for (String fileName : filePaths) { Loading
packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +6 −128 Original line number Diff line number Diff line Loading @@ -30,19 +30,20 @@ import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Xml; import android.util.proto.ProtoOutputStream; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.TypedXmlSerializer; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.DisableFlags; import android.platform.test.flag.junit.SetFlagsRule; import com.google.common.base.Strings; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; Loading @@ -51,11 +52,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class SettingsStateTest { Loading Loading @@ -1084,124 +1080,6 @@ public class SettingsStateTest { assertTrue(flag1.getHasLocalOverride()); } @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Test @EnableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) public void testHandleBulkSyncWithAconfigdEnabled() { int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); Object lock = new Object(); SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey, SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); Map<String, AconfigdFlagInfo> flags = new HashMap<>(); flags.put( "com.android.flags/flag1", AconfigdFlagInfo.newBuilder() .setPackageName("com.android.flags") .setFlagName("flag1") .setBootFlagValue("true") .setIsReadWrite(true) .build()); flags.put( "com.android.flags/flag2", AconfigdFlagInfo.newBuilder() .setPackageName("com.android.flags") .setFlagName("flag2") .setBootFlagValue("true") .setIsReadWrite(false) .build()); String bulkSyncMarker = "aconfigd_marker/bulk_synced"; String bulkSyncCounter = "core_experiments_team_internal/" + "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; synchronized (lock) { settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); // first bulk sync ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); assertTrue(requests != null); String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); // send time should no longer bulk sync requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); // won't sync if the marker is string settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // won't sync if the marker and counter value are the same settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("1", value); } } @Test @DisableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) public void testHandleBulkSyncWithAconfigdDisabled() { int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); Object lock = new Object(); SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey, SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); Map<String, AconfigdFlagInfo> flags = new HashMap<>(); String bulkSyncMarker = "aconfigd_marker/bulk_synced"; String bulkSyncCounter = "core_experiments_team_internal/" + "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; synchronized (lock) { settingsState.insertSettingLocked("aconfigd_marker/bulk_synced", "true", null, false, "aconfig"); // when aconfigd is off, should change the marker to false ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // marker started with false value, after call, it should remain false requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); // won't sync settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, "com.google.android.platform.core_experiments_team_internal"); requests = settingsState.handleBulkSyncToNewStorage(flags); assertNull(requests); value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); assertEquals("0", value); } } @Test public void testGetAllAconfigFlagsFromSettings() throws Exception { final Object lock = new Object(); Loading