1 /* 2 * Copyright (C) 2022 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.wifi; 18 19 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_THREAD_TASK_EXECUTED; 20 21 import android.annotation.NonNull; 22 import android.os.Message; 23 import android.os.Trace; 24 import android.util.LocalLog; 25 26 import com.android.internal.util.State; 27 import com.android.server.wifi.proto.WifiStatsLog; 28 29 /** 30 * RunnerState class is a wrapper based on State class to monitor and track the State enter/exit 31 * and message handler execution for taking longer time than the expected threshold. 32 * User must extend the RunnerState class instead of State, and provide the implementation of: 33 * { @link RunnerState#enterImpl() } { @link RunnerState#exitImpl() } 34 * { @link RunnerState#processMessageImpl() } 35 * { @link RunnerState#getMessageLogRec() } 36 * 37 */ 38 public abstract class RunnerState extends State { 39 private static final String TAG = "RunnerState"; 40 private static final int METRICS_THRESHOLD_MILLIS = 100; 41 42 /** Message.what value when entering */ 43 public static final int STATE_ENTER_CMD = -3; 44 45 /** Message.what value when exiting */ 46 public static final int STATE_EXIT_CMD = -4; 47 48 private final int mRunningTimeThresholdInMilliseconds; 49 // TODO: b/246623192 Add Wifi metric for Runner state overruns. 50 private final LocalLog mLocalLog; 51 52 /** 53 * The Runner state Constructor 54 * @param threshold the running time threshold in milliseconds 55 */ RunnerState(int threshold, @NonNull LocalLog localLog)56 public RunnerState(int threshold, @NonNull LocalLog localLog) { 57 mRunningTimeThresholdInMilliseconds = threshold; 58 mLocalLog = localLog; 59 } 60 61 @Override processMessage(Message message)62 public boolean processMessage(Message message) { 63 long startTime = System.currentTimeMillis(); 64 65 String signatureToLog = getMessageLogRec(message); 66 if (signatureToLog == null) { 67 signatureToLog = getMessageLogRec(message.what); 68 } 69 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, signatureToLog); 70 boolean ret = processMessageImpl(message); 71 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 72 long runTime = System.currentTimeMillis() - startTime; 73 if (runTime > mRunningTimeThresholdInMilliseconds) { 74 mLocalLog.log(signatureToLog + " was running for " + runTime + " ms"); 75 } 76 if (runTime > METRICS_THRESHOLD_MILLIS) { 77 WifiStatsLog.write(WIFI_THREAD_TASK_EXECUTED, (int) runTime, 0, signatureToLog); 78 } 79 return ret; 80 } 81 82 @Override enter()83 public void enter() { 84 long startTime = System.currentTimeMillis(); 85 String signatureToLog = getMessageLogRec(STATE_ENTER_CMD); 86 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, signatureToLog); 87 enterImpl(); 88 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 89 long runTime = System.currentTimeMillis() - startTime; 90 if (runTime > mRunningTimeThresholdInMilliseconds) { 91 mLocalLog.log(signatureToLog + " was running for " + runTime + " ms"); 92 } 93 if (runTime > METRICS_THRESHOLD_MILLIS) { 94 WifiStatsLog.write(WIFI_THREAD_TASK_EXECUTED, (int) runTime, 0, signatureToLog); 95 } 96 } 97 98 @Override exit()99 public void exit() { 100 long startTime = System.currentTimeMillis(); 101 String signatureToLog = getMessageLogRec(STATE_EXIT_CMD); 102 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, signatureToLog); 103 exitImpl(); 104 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 105 long runTime = System.currentTimeMillis() - startTime; 106 if (runTime > mRunningTimeThresholdInMilliseconds) { 107 mLocalLog.log(signatureToLog + " was running for " + runTime + " ms"); 108 } 109 if (runTime > METRICS_THRESHOLD_MILLIS) { 110 WifiStatsLog.write(WIFI_THREAD_TASK_EXECUTED, (int) runTime, 0, signatureToLog); 111 } 112 } 113 114 /** 115 * Implement this method for State enter process, instead of enter() 116 */ enterImpl()117 public abstract void enterImpl(); 118 119 /** 120 * Implement this method for State exit process, instead of exit() 121 */ exitImpl()122 public abstract void exitImpl(); 123 124 /** 125 * Implement this method for process message, instead of processMessage() 126 */ processMessageImpl(Message msg)127 public abstract boolean processMessageImpl(Message msg); 128 129 /** 130 * Implement this to translate a message `what` into a readable String 131 * @param what message 'what' field 132 * @return Readable string 133 */ getMessageLogRec(int what)134 public String getMessageLogRec(int what) { 135 return null; 136 }; 137 138 /** 139 * Implement this to translate a message into a readable String 140 * @return Readable string 141 */ getMessageLogRec(Message message)142 public String getMessageLogRec(Message message) { 143 return null; 144 }; 145 } 146