1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.junit.Assert.assertEquals; 25 import static org.mockito.ArgumentMatchers.any; 26 27 import android.app.ActivityThread; 28 import android.platform.test.annotations.Presubmit; 29 import android.provider.DeviceConfig; 30 31 import androidx.test.filters.SmallTest; 32 33 import com.android.modules.utils.testing.TestableDeviceConfig; 34 35 import org.junit.After; 36 import org.junit.Assert; 37 import org.junit.Before; 38 import org.junit.Rule; 39 import org.junit.Test; 40 41 import java.util.Objects; 42 import java.util.concurrent.CountDownLatch; 43 import java.util.concurrent.Executor; 44 import java.util.concurrent.TimeUnit; 45 46 /** 47 * Test class for {@link SynchedDeviceConfig}. 48 * 49 * atest WmTests:SynchedDeviceConfigTests 50 */ 51 @SmallTest 52 @Presubmit 53 public class SynchedDeviceConfigTests { 54 55 private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec 56 private static final String NAMESPACE_FOR_TEST = "TestingNameSpace"; 57 58 private SynchedDeviceConfig mDeviceConfig; 59 60 private Executor mExecutor; 61 62 @Rule 63 public final TestableDeviceConfig.TestableDeviceConfigRule 64 mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule(); 65 66 @Before setUp()67 public void setUp() { 68 mExecutor = Objects.requireNonNull(ActivityThread.currentApplication()).getMainExecutor(); 69 mDeviceConfig = SynchedDeviceConfig 70 .builder(/* nameSpace */ NAMESPACE_FOR_TEST, /* executor */ mExecutor) 71 .addDeviceConfigEntry(/* key */ "key1", /* default */ true, /* enabled */ true) 72 .addDeviceConfigEntry(/* key */ "key2", /* default */ false, /* enabled */ true) 73 .addDeviceConfigEntry(/* key */ "key3", /* default */ true, /* enabled */ false) 74 .addDeviceConfigEntry(/* key */ "key4", /* default */ false, /* enabled */ false) 75 .build(); 76 } 77 78 @After tearDown()79 public void tearDown() { 80 DeviceConfig.removeOnPropertiesChangedListener(mDeviceConfig); 81 } 82 83 @Test testWhenStarted_initialValuesAreDefaultOrFalseIfDisabled()84 public void testWhenStarted_initialValuesAreDefaultOrFalseIfDisabled() { 85 assertFlagValue(/* key */ "key1", /* expected */ true); // enabled 86 assertFlagValue(/* key */ "key2", /* expected */ false); // enabled 87 assertFlagValue(/* key */ "key3", /* expected */ false); // disabled 88 assertFlagValue(/* key */ "key4", /* expected */ false); // disabled 89 } 90 91 @Test testIsEnabled()92 public void testIsEnabled() { 93 assertFlagEnabled(/* key */ "key1", /* expected */ true); 94 assertFlagEnabled(/* key */ "key2", /* expected */ true); 95 assertFlagEnabled(/* key */ "key3", /* expected */ false); 96 assertFlagEnabled(/* key */ "key4", /* expected */ false); 97 } 98 99 @Test testWhenUpdated_onlyEnabledChanges()100 public void testWhenUpdated_onlyEnabledChanges() { 101 final CountDownLatch countDownLatch = new CountDownLatch(4); 102 spyOn(mDeviceConfig); 103 doAnswer(invocation -> { 104 invocation.callRealMethod(); 105 countDownLatch.countDown(); 106 return null; 107 }).when(mDeviceConfig).onPropertiesChanged(any()); 108 try { 109 // We update all the keys 110 updateProperty(/* key */ "key1", /* value */ false); 111 updateProperty(/* key */ "key2", /* value */ true); 112 updateProperty(/* key */ "key3", /* value */ false); 113 updateProperty(/* key */ "key4", /* value */ true); 114 115 assertThat(countDownLatch.await( 116 WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue(); 117 118 // We update all the flags but only the enabled ones change 119 assertFlagValue(/* key */ "key1", /* expected */ false); // changes 120 assertFlagValue(/* key */ "key2", /* expected */ true); // changes 121 assertFlagValue(/* key */ "key3", /* expected */ false); // disabled 122 assertFlagValue(/* key */ "key4", /* expected */ false); // disabled 123 } catch (InterruptedException e) { 124 Assert.fail(e.getMessage()); 125 } 126 } 127 assertFlagValue(String key, boolean expectedValue)128 private void assertFlagValue(String key, boolean expectedValue) { 129 assertEquals(/* message */"Flag " + key + " value is not " + expectedValue, /* expected */ 130 expectedValue, /* actual */ mDeviceConfig.getFlagValue(key)); 131 } 132 133 assertFlagEnabled(String key, boolean expectedValue)134 private void assertFlagEnabled(String key, boolean expectedValue) { 135 assertEquals(/* message */ 136 "Flag " + key + " enabled is not " + expectedValue, /* expected */ 137 expectedValue, /* actual */ mDeviceConfig.isBuildTimeFlagEnabled(key)); 138 } 139 updateProperty(String key, Boolean value)140 private void updateProperty(String key, Boolean value) { 141 DeviceConfig.setProperty(NAMESPACE_FOR_TEST, key, /* value */ 142 value.toString(), /* makeDefault */ false); 143 } 144 } 145