1/* 2 * Copyright (C) 2017 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 */ 16package com.android.statsd.loadtest; 17 18import android.util.Log; 19import android.util.StatsLog; 20 21import java.util.ArrayList; 22import java.util.List; 23 24/** 25 * Manages the pushing of atoms into logd for loadtesting. 26 * We rely on small number of pushed atoms, and a config with metrics based on those atoms. 27 * The atoms are: 28 * <ul> 29 * <li> BatteryLevelChanged - For EventMetric, CountMetric and GaugeMetric (no dimensions). 30 * <li> BleScanResultReceived - For CountMetric and ValueMetric, sliced by uid. 31 * <li> ChargingStateChanged - For DurationMetric (no dimension). 32 * <li> GpsScanStateChanged - For DurationMetric, sliced by uid. 33 * <li> ScreenStateChanged - For Conditions with no dimensions. 34 * <li> AudioStateChanged - For Conditions with dimensions (uid). 35 * </ul> 36 * The sequence is played over and over at a given frequency. 37 */ 38public class SequencePusher { 39 private static final String TAG = "SequencePusher"; 40 41 /** Some atoms are pushed in burst of {@code mBurst} events. */ 42 private final int mBurst; 43 44 /** If this is true, we don't log anything in logd. */ 45 private final boolean mPlacebo; 46 47 /** Current state in the automaton. */ 48 private int mCursor = 0; 49 50 public SequencePusher(int burst, boolean placebo) { 51 mBurst = burst; 52 mPlacebo = placebo; 53 } 54 55 /** 56 * Pushes the next atom to logd. 57 * This follows a small automaton which makes the right events and conditions overlap: 58 * (0) Push a burst of BatteryLevelChanged atoms. 59 * (1) Push a burst of BleScanResultReceived atoms. 60 * (2) Push ChargingStateChanged with BATTERY_STATUS_CHARGING once. 61 * (3) Push a burst of GpsScanStateChanged atoms with ON, with a different uid each time. 62 * (4) Push ChargingStateChanged with BATTERY_STATUS_NOT_CHARGING once. 63 * (5) Push a burst GpsScanStateChanged atoms with OFF, with a different uid each time. 64 * (6) Push ScreenStateChanged with STATE_ON once. 65 * (7) Push a burst of AudioStateChanged with ON, with a different uid each time. 66 * (8) Repeat steps (0)-(5). 67 * (9) Push ScreenStateChanged with STATE_OFF once. 68 * (10) Push a burst of AudioStateChanged with OFF, with a different uid each time. 69 * and repeat. 70 */ 71 public void next() { 72 Log.d(TAG, "Next step: " + mCursor); 73 if (mPlacebo) { 74 return; 75 } 76 switch (mCursor) { 77 case 0: 78 case 8: 79 for (int i = 0; i < mBurst; i++) { 80 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, 50 + i /* battery_level */); 81 } 82 break; 83 case 1: 84 case 9: 85 for (int i = 0; i < mBurst; i++) { 86 StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, i /* uid */, 87 100 /* num_of_results */); 88 } 89 break; 90 case 2: 91 case 10: 92 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, 93 StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_CHARGING 94 /* charging_state */); 95 break; 96 case 3: 97 case 11: 98 for (int i = 0; i < mBurst; i++) { 99 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */, 100 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON /* state */); 101 } 102 break; 103 case 4: 104 case 12: 105 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, 106 StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING 107 /* charging_state */); 108 break; 109 case 5: 110 case 13: 111 for (int i = 0; i < mBurst; i++) { 112 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */, 113 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */); 114 } 115 break; 116 case 6: 117 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, 118 StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON /* display_state */); 119 break; 120 case 7: 121 for (int i = 0; i < mBurst; i++) { 122 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */, 123 StatsLog.AUDIO_STATE_CHANGED__STATE__ON /* state */); 124 } 125 break; 126 case 14: 127 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, 128 StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */); 129 break; 130 case 15: 131 for (int i = 0; i < mBurst; i++) { 132 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */, 133 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */); 134 } 135 break; 136 default: 137 } 138 mCursor++; 139 if (mCursor > 15) { 140 mCursor = 0; 141 } 142 } 143 144 /** 145 * Properly finishes in order to be close all conditions and durations. 146 */ 147 public void finish() { 148 // Screen goes back to off. This will ensure that conditions get back to false. 149 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, 150 StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */); 151 for (int i = 0; i < mBurst; i++) { 152 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */, 153 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */); 154 } 155 // Stop charging, to ensure the corresponding durations are closed. 156 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, 157 StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING 158 /* charging_state */); 159 // Stop scanning GPS, to ensure the corresponding conditions get back to false. 160 for (int i = 0; i < mBurst; i++) { 161 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */, 162 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */); 163 } 164 } 165} 166