1 /*
2  * Copyright (C) 2024 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.deviceconfig;
18 
19 
20 import static com.android.server.deviceconfig.Flags.FLAG_ENABLE_CUSTOM_REBOOT_TIME_CONFIGURATIONS;
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.Mockito.when;
24 
25 import android.content.Context;
26 import android.content.res.Resources;
27 import android.platform.test.flag.junit.SetFlagsRule;
28 import android.util.Pair;
29 
30 import androidx.test.filters.SmallTest;
31 
32 import com.android.server.deviceconfig.resources.R;
33 
34 import org.junit.Before;
35 import org.junit.Rule;
36 import org.junit.Test;
37 import org.mockito.Mock;
38 import org.mockito.junit.MockitoJUnit;
39 import org.mockito.junit.MockitoRule;
40 
41 import java.util.Optional;
42 
43 @SmallTest
44 public class RebootTimingConfigurationTest {
45 
46     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
47     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
48 
49     private static final String TEST_RESOURCES_PACKAGE_NAME =
50             "abc.android.server.deviceconfig.resources";
51 
52     @Mock private Context mContext;
53     @Mock private Resources mResources;
54     @Mock private ServiceResourcesHelper mResourcesHelper;
55 
56     @Before
setUp()57     public void setUp() throws Exception {
58         mSetFlagsRule.enableFlags(FLAG_ENABLE_CUSTOM_REBOOT_TIME_CONFIGURATIONS);
59         ServiceResourcesHelper.setInstanceForTest(mResourcesHelper);
60         when(mResourcesHelper.getResourcesPackageName())
61                 .thenReturn(Optional.of(TEST_RESOURCES_PACKAGE_NAME));
62         when(mContext.createPackageContext(TEST_RESOURCES_PACKAGE_NAME, 0))
63                 .thenReturn(mContext);
64         when(mContext.getResources()).thenReturn(mResources);
65     }
66 
67     @Test
validSameDayConfiguration()68     public void validSameDayConfiguration() {
69         mockRebootWindowConfig(1, 3);
70         mockRebootFrequencyDays(4);
71 
72         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
73 
74         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(1, 3)));
75         assertThat(config.getRebootFrequencyDays()).isEqualTo(4);
76         assertHoursWithinWindow(config, 1, 2);
77         assertHoursOutsideWindow(config, 0, 3, 4);
78     }
79 
80     @Test
validNextDayConfiguration()81     public void validNextDayConfiguration() {
82         mockRebootWindowConfig(22, 3);
83         mockRebootFrequencyDays(4);
84 
85         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
86 
87         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(22, 3)));
88         assertThat(config.getRebootFrequencyDays()).isEqualTo(4);
89         assertHoursWithinWindow(config, 22, 23, 0, 1, 2);
90         assertHoursOutsideWindow(config, 20, 3, 4);
91     }
92 
93     @Test
flagDisabled_usesDefaultWindowAndFrequency()94     public void flagDisabled_usesDefaultWindowAndFrequency() {
95         mSetFlagsRule.disableFlags(FLAG_ENABLE_CUSTOM_REBOOT_TIME_CONFIGURATIONS);
96         mockRebootWindowConfig(1, 9);
97         mockRebootFrequencyDays(4);
98 
99         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
100 
101         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(3, 5)));
102         assertThat(config.getRebootFrequencyDays()).isEqualTo(2);
103     }
104 
105     @Test
invalidWindowHoursWithEqualWindowTimes_usesDefaultWindow()106     public void invalidWindowHoursWithEqualWindowTimes_usesDefaultWindow() {
107         mockRebootWindowConfig(1, 1);
108         mockRebootFrequencyDays(4);
109 
110         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
111 
112         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(3, 5)));
113         assertThat(config.getRebootFrequencyDays()).isEqualTo(4);
114     }
115 
116     @Test
invalidWindowHoursWithNegativeWindowTimes_usesDefaultWindow()117     public void invalidWindowHoursWithNegativeWindowTimes_usesDefaultWindow() {
118         mockRebootWindowConfig(-1, 1);
119         mockRebootFrequencyDays(4);
120 
121         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
122 
123         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(3, 5)));
124         assertThat(config.getRebootFrequencyDays()).isEqualTo(4);
125     }
126 
127     @Test
invalidFrequencyDay_usesDefaultFrequencyDay()128     public void invalidFrequencyDay_usesDefaultFrequencyDay() {
129         mockRebootWindowConfig(2, 3);
130         mockRebootFrequencyDays(-4);
131 
132         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
133 
134         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.of(Pair.create(2, 3)));
135         assertThat(config.getRebootFrequencyDays()).isEqualTo(2);
136     }
137 
138     @Test
disableRebootWindowConfiguration()139     public void disableRebootWindowConfiguration() {
140         mockRebootWindowConfig(-1, -1);
141         mockRebootFrequencyDays(4);
142 
143         RebootTimingConfiguration config = new RebootTimingConfiguration(mContext);
144 
145         assertThat(config.getRebootWindowStartEndHour()).isEqualTo(Optional.empty());
146         assertThat(config.getRebootFrequencyDays()).isEqualTo(4);
147         for (int i = 0; i < 24; i++) {
148             assertHoursWithinWindow(config, i);
149         }
150     }
151 
mockRebootWindowConfig(int windowStartHour, int windowEndHour)152     private void mockRebootWindowConfig(int windowStartHour, int windowEndHour) {
153         when(mResources.getInteger(R.integer.config_unattendedRebootStartHour))
154                 .thenReturn(windowStartHour);
155         when(mResources.getInteger(R.integer.config_unattendedRebootEndHour))
156                 .thenReturn(windowEndHour);
157     }
158 
mockRebootFrequencyDays(int days)159     private void mockRebootFrequencyDays(int days) {
160         when(mResources.getInteger(R.integer.config_unattendedRebootFrequencyDays))
161                 .thenReturn(days);
162     }
163 
assertHoursWithinWindow(RebootTimingConfiguration config, int... hours)164     private void assertHoursWithinWindow(RebootTimingConfiguration config, int... hours) {
165         for (int hour : hours) {
166             assertThat(config.isHourWithinRebootHourWindow(hour)).isTrue();
167         }
168     }
169 
assertHoursOutsideWindow(RebootTimingConfiguration config, int... hours)170     private void assertHoursOutsideWindow(RebootTimingConfiguration config, int... hours) {
171         for (int hour : hours) {
172             assertThat(config.isHourWithinRebootHourWindow(hour)).isFalse();
173         }
174     }
175 }
176