Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc2c51a9 authored by Tianjie Xu's avatar Tianjie Xu Committed by Gerrit Code Review
Browse files

Merge "Log temperature during OTA update"

parents 713d9156 3ee2b9db
Loading
Loading
Loading
Loading
+47 −5
Original line number Diff line number Diff line
@@ -26,11 +26,15 @@
#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <limits>
#include <map>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <android-base/file.h>
@@ -46,10 +50,13 @@
#include "error_code.h"
#include "minui/minui.h"
#include "otautil/SysUtil.h"
#include "otautil/ThermalUtil.h"
#include "roots.h"
#include "ui.h"
#include "verifier.h"

using namespace std::chrono_literals;

#define ASSUMED_UPDATE_BINARY_NAME  "META-INF/com/google/android/update-binary"
static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
@@ -63,6 +70,8 @@ static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
static constexpr float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
static constexpr float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;

static std::condition_variable finish_log_temperature;

// This function parses and returns the build.version.incremental
static int parse_build_number(const std::string& str) {
    size_t pos = str.find('=');
@@ -299,9 +308,19 @@ update_binary_command(const char* path, ZipArchiveHandle zip, int retry_count,
}
#endif  // !AB_OTA_UPDATER

static void log_max_temperature(int* max_temperature) {
  CHECK(max_temperature != nullptr);
  std::mutex mtx;
  std::unique_lock<std::mutex> lck(mtx);
  while (finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
    *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
  }
}

// If the package contains an update binary, extract it and run it.
static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_cache,
                             std::vector<std::string>& log_buffer, int retry_count) {
                             std::vector<std::string>& log_buffer, int retry_count,
                             int* max_temperature) {
  read_source_target_build(zip, log_buffer);

  int pipefd[2];
@@ -392,6 +411,8 @@ static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_
  }
  close(pipefd[1]);

  std::thread temperature_logger(log_max_temperature, max_temperature);

  *wipe_cache = false;
  bool retry_update = false;

@@ -453,6 +474,10 @@ static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_

  int status;
  waitpid(pid, &status, 0);

  finish_log_temperature.notify_one();
  temperature_logger.join();

  if (retry_update) {
    return INSTALL_RETRY;
  }
@@ -466,7 +491,7 @@ static int try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_

static int
really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
                       std::vector<std::string>& log_buffer, int retry_count)
                       std::vector<std::string>& log_buffer, int retry_count, int* max_temperature)
{
    ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
    ui->Print("Finding update package...\n");
@@ -517,7 +542,7 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
        ui->Print("Retry attempt: %d\n", retry_count);
    }
    ui->SetEnableReboot(false);
    int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count);
    int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
    ui->SetEnableReboot(true);
    ui->Print("\n");

@@ -533,13 +558,17 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
    modified_flash = true;
    auto start = std::chrono::system_clock::now();

    int start_temperature = GetMaxValueFromThermalZone();
    int max_temperature = start_temperature;

    int result;
    std::vector<std::string> log_buffer;
    if (setup_install_mounts() != 0) {
        LOG(ERROR) << "failed to set up expected mounts for install; aborting";
        result = INSTALL_ERROR;
    } else {
        result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count);
        result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count,
                                        &max_temperature);
    }

    // Measure the time spent to apply OTA update in seconds.
@@ -570,8 +599,21 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
        "time_total: " + std::to_string(time_total),
        "retry: " + std::to_string(retry_count),
    };

    int end_temperature = GetMaxValueFromThermalZone();
    max_temperature = std::max(end_temperature, max_temperature);
    if (start_temperature > 0) {
      log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
    }
    if (end_temperature > 0) {
      log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
    }
    if (max_temperature > 0) {
      log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
    }

    std::string log_content = android::base::Join(log_header, "\n") + "\n" +
            android::base::Join(log_buffer, "\n");
            android::base::Join(log_buffer, "\n") + "\n";
    if (!android::base::WriteStringToFile(log_content, install_file)) {
        PLOG(ERROR) << "failed to write " << install_file;
    }
+8 −4
Original line number Diff line number Diff line
@@ -18,12 +18,16 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    SysUtil.cpp \
    DirUtil.cpp \
    ZipUtil.cpp
    ZipUtil.cpp \
    ThermalUtil.cpp

LOCAL_STATIC_LIBRARIES := libselinux libbase
LOCAL_STATIC_LIBRARIES := \
    libselinux \
    libbase

LOCAL_MODULE := libotautil

LOCAL_CFLAGS += -Werror -Wall
LOCAL_CFLAGS := \
    -Werror \
    -Wall

include $(BUILD_STATIC_LIBRARY)
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#include "ThermalUtil.h"

#include <dirent.h>
#include <stdio.h>

#include <algorithm>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>

static constexpr auto THERMAL_PREFIX = "/sys/class/thermal/";

static int thermal_filter(const dirent* de) {
  if (android::base::StartsWith(de->d_name, "thermal_zone")) {
    return 1;
  }
  return 0;
}

static std::vector<std::string> InitThermalPaths() {
  dirent** namelist;
  int n = scandir(THERMAL_PREFIX, &namelist, thermal_filter, alphasort);
  if (n == -1) {
    PLOG(ERROR) << "Failed to scandir " << THERMAL_PREFIX;
    return {};
  }
  if (n == 0) {
    LOG(ERROR) << "Failed to find CPU thermal info in " << THERMAL_PREFIX;
    return {};
  }

  std::vector<std::string> thermal_paths;
  while (n--) {
    thermal_paths.push_back(THERMAL_PREFIX + std::string(namelist[n]->d_name) + "/temp");
    free(namelist[n]);
  }
  free(namelist);
  return thermal_paths;
}

int GetMaxValueFromThermalZone() {
  static std::vector<std::string> thermal_paths = InitThermalPaths();
  int max_temperature = -1;
  for (const auto& path : thermal_paths) {
    std::string content;
    if (!android::base::ReadFileToString(path, &content)) {
      PLOG(WARNING) << "Failed to read " << path;
      continue;
    }

    int temperature;
    if (!android::base::ParseInt(android::base::Trim(content), &temperature)) {
      LOG(WARNING) << "Failed to parse integer in " << content;
      continue;
    }
    max_temperature = std::max(temperature, max_temperature);
  }
  LOG(INFO) << "current maximum temperature: " << max_temperature;
  return max_temperature;
}
 No newline at end of file

otautil/ThermalUtil.h

0 → 100644
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef OTAUTIL_THERMALUTIL_H
#define OTAUTIL_THERMALUTIL_H

// We can find the temperature reported by all sensors in /sys/class/thermal/thermal_zone*/temp.
// Their values are in millidegree Celsius; and we will log the maximum one.
int GetMaxValueFromThermalZone();

#endif  // OTAUTIL_THERMALUTIL_H