1 /* 2 * Copyright (C) 2021 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 android.time.cts.host; 18 19 import static android.app.time.cts.shell.LocationTimeZoneManagerShellHelper.PRIMARY_PROVIDER_INDEX; 20 import static android.app.time.cts.shell.LocationTimeZoneManagerShellHelper.PROVIDER_MODE_DISABLED; 21 import static android.app.time.cts.shell.LocationTimeZoneManagerShellHelper.PROVIDER_MODE_SIMULATED; 22 import static android.app.time.cts.shell.LocationTimeZoneManagerShellHelper.SECONDARY_PROVIDER_INDEX; 23 24 import static java.util.stream.Collectors.toList; 25 26 import android.cts.statsdatom.lib.AtomTestUtils; 27 import android.cts.statsdatom.lib.ConfigUtils; 28 import android.cts.statsdatom.lib.DeviceUtils; 29 import android.cts.statsdatom.lib.ReportUtils; 30 31 import com.android.os.AtomsProto; 32 import com.android.os.AtomsProto.LocationTimeZoneProviderStateChanged; 33 import com.android.os.StatsLog; 34 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 35 36 import org.junit.After; 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.util.Arrays; 42 import java.util.Collections; 43 import java.util.List; 44 import java.util.Set; 45 import java.util.function.Function; 46 47 /** Host-side CTS tests for the location time zone manager service stats logging. */ 48 @RunWith(DeviceJUnit4ClassRunner.class) 49 public class LocationTimeZoneManagerStatsTest extends BaseLocationTimeZoneManagerHostTest { 50 51 private static final int PROVIDER_STATES_COUNT = 52 LocationTimeZoneProviderStateChanged.State.values().length; 53 54 @Before 55 @Override setUp()56 public void setUp() throws Exception { 57 super.setUp(); 58 ConfigUtils.removeConfig(getDevice()); 59 ReportUtils.clearReports(getDevice()); 60 } 61 62 @After 63 @Override tearDown()64 public void tearDown() throws Exception { 65 ConfigUtils.removeConfig(getDevice()); 66 ReportUtils.clearReports(getDevice()); 67 super.tearDown(); 68 } 69 70 @Test testAtom_locationTimeZoneProviderStateChanged()71 public void testAtom_locationTimeZoneProviderStateChanged() throws Exception { 72 setProviderModeOverride(PRIMARY_PROVIDER_INDEX, PROVIDER_MODE_DISABLED); 73 setProviderModeOverride(SECONDARY_PROVIDER_INDEX, PROVIDER_MODE_SIMULATED); 74 mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(false); 75 76 startLocationTimeZoneManagerService(); 77 78 ConfigUtils.uploadConfigForPushedAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 79 AtomsProto.Atom.LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED_FIELD_NUMBER); 80 81 // Turn geo detection on and off, twice. 82 for (int i = 0; i < 2; i++) { 83 mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true); 84 Thread.sleep(AtomTestUtils.WAIT_TIME_SHORT); 85 mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(false); 86 Thread.sleep(AtomTestUtils.WAIT_TIME_SHORT); 87 } 88 89 // Sorted list of events in order in which they occurred. 90 List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 91 92 // States. 93 Set<Integer> primaryProviderStarted = singletonStateId(PRIMARY_PROVIDER_INDEX, 94 LocationTimeZoneProviderStateChanged.State.INITIALIZING); 95 Set<Integer> primaryProviderFailed = singletonStateId(PRIMARY_PROVIDER_INDEX, 96 LocationTimeZoneProviderStateChanged.State.PERM_FAILED); 97 Set<Integer> secondaryProviderStarted = singletonStateId(SECONDARY_PROVIDER_INDEX, 98 LocationTimeZoneProviderStateChanged.State.INITIALIZING); 99 Set<Integer> secondaryProviderStopped = singletonStateId(SECONDARY_PROVIDER_INDEX, 100 LocationTimeZoneProviderStateChanged.State.STOPPED); 101 Function<AtomsProto.Atom, Integer> eventToStateFunction = atom -> { 102 int providerIndex = atom.getLocationTimeZoneProviderStateChanged().getProviderIndex(); 103 return stateId(providerIndex, 104 atom.getLocationTimeZoneProviderStateChanged().getState()); 105 }; 106 107 // Add state sets to the list in order. 108 // Assert that the events happened in the expected order. This does not check "wait" (the 109 // time between events). 110 List<Set<Integer>> stateSets = Arrays.asList( 111 primaryProviderStarted, primaryProviderFailed, 112 secondaryProviderStarted, secondaryProviderStopped, 113 secondaryProviderStarted, secondaryProviderStopped); 114 AtomTestUtils.assertStatesOccurred(stateSets, data, 115 0 /* wait */, eventToStateFunction); 116 117 // Assert that the events for the secondary provider happened in the expected order. This 118 // does check "wait" (the time between events). 119 List<StatsLog.EventMetricData> secondaryEvents = 120 extractEventsForProviderIndex(data, SECONDARY_PROVIDER_INDEX); 121 List<Set<Integer>> secondaryStateSets = Arrays.asList( 122 secondaryProviderStarted, secondaryProviderStopped, 123 secondaryProviderStarted, secondaryProviderStopped); 124 AtomTestUtils.assertStatesOccurred(secondaryStateSets, secondaryEvents, 125 AtomTestUtils.WAIT_TIME_SHORT /* wait */, eventToStateFunction); 126 } 127 singletonStateId(int providerIndex, LocationTimeZoneProviderStateChanged.State state)128 private static Set<Integer> singletonStateId(int providerIndex, 129 LocationTimeZoneProviderStateChanged.State state) { 130 return Collections.singleton(stateId(providerIndex, state)); 131 } 132 extractEventsForProviderIndex( List<StatsLog.EventMetricData> data, int providerIndex)133 private static List<StatsLog.EventMetricData> extractEventsForProviderIndex( 134 List<StatsLog.EventMetricData> data, int providerIndex) { 135 return data.stream().filter(event -> { 136 if (!event.getAtom().hasLocationTimeZoneProviderStateChanged()) { 137 return false; 138 } 139 return event.getAtom().getLocationTimeZoneProviderStateChanged().getProviderIndex() 140 == providerIndex; 141 }).collect(toList()); 142 } 143 144 /** Maps a (provider index, provider state) pair to an integer state ID. */ 145 private static Integer stateId( 146 int providerIndex, LocationTimeZoneProviderStateChanged.State providerState) { 147 return (providerIndex * PROVIDER_STATES_COUNT) + providerState.getNumber(); 148 } 149 } 150