aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tradefed/targetprep/TemperatureThrottlingWaiter.java
blob: faaa85588943be81894d4d18d0d4428a87b3d62d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.tradefed.targetprep;

import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.util.RunUtil;

/**
 * An {@link ITargetPreparer} that waits until device's temperature gets down to target
 */
@OptionClass(alias = "temperature-throttle-waiter")
public class TemperatureThrottlingWaiter implements ITargetPreparer {

    @Option(name = "poll-interval",
            description = "Interval in seconds, to poll for device temperature; defaults to 30s")
    private long mPollIntervalSecs = 30;

    @Option(name = "max-wait", description = "Max wait time in seconds, for device cool down "
            + "to target temperature; defaults to 20 minutes")
    private long mMaxWaitSecs = 60 * 20;

    @Option(name = "abort-on-timeout", description = "If test should be aborted if device is still "
        + " above expected temperature; defaults to false")
    private boolean mAbortOnTimeout = false;

    @Option(name = "post-idle-wait", description = "Additional time to wait in seconds, after "
        + "temperature has reached to target; defaults to 120s")
    private long mPostIdleWaitSecs = 120;

    @Option(name = "device-temperature-file-path", description = "Name of file that contains device"
        + "temperature. Example: /sys/class/hwmon/hwmon1/device/msm_therm")
    private String mDeviceTemperatureFilePath = null;

    @Option(name = "target-temperature", description = "Target Temperature that device should have;"
        + "defaults to 30c")
    private int mTargetTemperature = 30;

    /**
     * {@inheritDoc}
     */
    @Override
    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
            BuildError, DeviceNotAvailableException {
        if (mDeviceTemperatureFilePath == null) {
            return;
        }
        long start = System.currentTimeMillis();
        long maxWaitMs = mMaxWaitSecs * 1000;
        long intervalMs = mPollIntervalSecs * 1000;
        int deviceTemperature = Integer.MAX_VALUE;
        while (true) {
            // get device temperature
            deviceTemperature = getDeviceTemperature(device, mDeviceTemperatureFilePath);
            if (deviceTemperature > mTargetTemperature) {
                CLog.d("Temperature is still high actual %d/expected %d",
                        deviceTemperature, mTargetTemperature);
            } else {
                CLog.i("Total time elapsed to get to %dc : %ds", mTargetTemperature,
                        (System.currentTimeMillis() - start) / 1000);
                break; // while loop
            }
            if ((System.currentTimeMillis() - start) > maxWaitMs) {
                CLog.w("Temperature is still high, actual %d/expected %d; waiting after %ds",
                        deviceTemperature, mTargetTemperature, maxWaitMs);
                if (mAbortOnTimeout) {
                    throw new TargetSetupError(String.format("Temperature is still high after wait "
                            + "timeout; actual %d/expected %d", deviceTemperature,
                            mTargetTemperature), device.getDeviceDescriptor());
                }
                break; // while loop
            }
            RunUtil.getDefault().sleep(intervalMs);
        }
        // extra idle time after reaching the targetl to stable the system
        RunUtil.getDefault().sleep(mPostIdleWaitSecs * 1000);
        CLog.d("Done waiting, total time elapsed: %ds",
                (System.currentTimeMillis() - start) / 1000);
    }

    /**
     * @param device
     * @param fileName : filename where device temperature is stored
     * @throws DeviceNotAvailableException
     */
    protected int getDeviceTemperature (ITestDevice device, String fileName)
            throws DeviceNotAvailableException, TargetSetupError {
        int deviceTemp = Integer.MAX_VALUE;
        String result = device.executeShellCommand(
                String.format("cat %s", fileName)).trim();
        CLog.i(String.format("Temperature file output : %s", result));
        // example output : Result:30 Raw:7f6f
        if (result == null || result.contains("No such file or directory")) {
            throw new TargetSetupError(String.format("File %s doesn't exist", fileName),
                    device.getDeviceDescriptor());
        } else if (!result.toLowerCase().startsWith("result:")) {
            throw new TargetSetupError(String.format("file content is not as expected. Content : ",
                    result), device.getDeviceDescriptor());
        }

        try {
            deviceTemp = Integer.parseInt(result.split(" ")[0].split(":")[1].trim());
        } catch (NumberFormatException numEx) {
            CLog.e(String.format("Temperature is not of right format + ", numEx.getMessage()));
            throw numEx;
        }

        return deviceTemp;
    }
}