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