#include <sys/klog.h>
#include <time.h>
#include <unistd.h>
+#include <vector>
#include <sys/prctl.h>
+#define LOG_TAG "dumpstate"
++
+ #include <android-base/file.h>
#include <cutils/debugger.h>
+#include <cutils/log.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
fclose(fp);
}
+/* overall progress */
+int progress = 0;
+int do_update_progress = 0; // Set by dumpstate.cpp
+int weight_total = WEIGHT_TOTAL;
+
+// TODO: make this function thread safe if sections are generated in parallel.
+void update_progress(int delta) {
+ if (!do_update_progress) return;
+
+ progress += delta;
+
+ char key[PROPERTY_KEY_MAX];
+ char value[PROPERTY_VALUE_MAX];
+
+ // adjusts max on the fly
+ if (progress > weight_total) {
+ int new_total = weight_total * 1.2;
+ MYLOGD("Adjusting total weight from %d to %d\n", weight_total, new_total);
+ weight_total = new_total;
+ snprintf(key, sizeof(key), "dumpstate.%d.max", getpid());
+ snprintf(value, sizeof(value), "%d", weight_total);
+ int status = property_set(key, value);
+ if (status) {
+ MYLOGE("Could not update max weight by setting system property %s to %s: %d\n",
+ key, value, status);
+ }
+ }
+
+ snprintf(key, sizeof(key), "dumpstate.%d.progress", getpid());
+ snprintf(value, sizeof(value), "%d", progress);
+
+ if (progress % 100 == 0) {
+ // We don't want to spam logcat, so only log multiples of 100.
+ MYLOGD("Setting progress (%s): %s/%d\n", key, value, weight_total);
+ } else {
+ // stderr is ignored on normal invocations, but useful when calling /system/bin/dumpstate
+ // directly for debuggging.
+ fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, weight_total);
+ }
+
+ int status = property_set(key, value);
+ if (status) {
+ MYLOGE("Could not update progress by setting system property %s to %s: %d\n",
+ key, value, status);
+ }
+}
+
+void take_screenshot(const std::string& path) {
+ const char *args[] = { "/system/bin/screencap", "-p", path.c_str(), NULL };
+ run_command_always(NULL, DONT_DROP_ROOT, REDIRECT_TO_STDERR, 10, args);
+}
+
+void vibrate(FILE* vibrator, int ms) {
+ fprintf(vibrator, "%d\n", ms);
+ fflush(vibrator);
+}
+
+bool is_dir(const char* pathname) {
+ struct stat info;
+ if (stat(pathname, &info) == -1) {
+ return false;
+ }
+ return S_ISDIR(info.st_mode);
+}
+
+time_t get_mtime(int fd, time_t default_mtime) {
+ struct stat info;
+ if (fstat(fd, &info) == -1) {
+ return default_mtime;
+ }
+ return info.st_mtime;
+}
+
void dump_emmc_ecsd(const char *ext_csd_path) {
- static const size_t EXT_CSD_REV = 192;
- static const size_t EXT_PRE_EOL_INFO = 267;
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268;
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269;
+ // List of interesting offsets
struct hex {
char str[2];
- } buffer[512];
- int fd, ext_csd_rev, ext_pre_eol_info;
- ssize_t bytes_read;
- static const char *ver_str[] = {
- "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
- };
- static const char *eol_str[] = {
- "Undefined",
- "Normal",
- "Warning (consumed 80% of reserve)",
- "Urgent (consumed 90% of reserve)"
};
+ static const size_t EXT_CSD_REV = 192 * sizeof(hex);
+ static const size_t EXT_PRE_EOL_INFO = 267 * sizeof(hex);
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268 * sizeof(hex);
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269 * sizeof(hex);
- printf("------ %s Extended CSD ------\n", ext_csd_path);
-
- fd = TEMP_FAILURE_RETRY(open(ext_csd_path,
- O_RDONLY | O_NONBLOCK | O_CLOEXEC));
- if (fd < 0) {
- printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+ std::string buffer;
+ if (!android::base::ReadFileToString(ext_csd_path, &buffer)) {
return;
}