Merge "Switch sdcardfs over to bind mounts." am: 94b9e4df04
am: 895cd44bd9

Change-Id: I33328d236f0ccfb9f65cfdc90d626a8561c032a1
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 740720b..c9876fd 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/ioctl.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/swap.h>
@@ -38,6 +39,7 @@
 #include <ext4_utils/ext4_sb.h>
 #include <ext4_utils/ext4_utils.h>
 #include <ext4_utils/wipe.h>
+#include <linux/fs.h>
 #include <linux/loop.h>
 #include <logwrap/logwrap.h>
 #include <private/android_filesystem_config.h>
@@ -50,8 +52,9 @@
 #define KEY_IN_FOOTER  "footer"
 
 #define E2FSCK_BIN      "/system/bin/e2fsck"
-#define F2FS_FSCK_BIN  "/system/bin/fsck.f2fs"
+#define F2FS_FSCK_BIN   "/system/bin/fsck.f2fs"
 #define MKSWAP_BIN      "/system/bin/mkswap"
+#define TUNE2FS_BIN     "/system/bin/tune2fs"
 
 #define FSCK_LOG_FILE   "/dev/fscklogs/log"
 
@@ -180,6 +183,99 @@
     return;
 }
 
+/* Function to read the primary superblock */
+static int read_super_block(int fd, struct ext4_super_block *sb)
+{
+    off64_t ret;
+
+    ret = lseek64(fd, 1024, SEEK_SET);
+    if (ret < 0)
+        return ret;
+
+    ret = read(fd, sb, sizeof(*sb));
+    if (ret < 0)
+        return ret;
+    if (ret != sizeof(*sb))
+        return ret;
+
+    return 0;
+}
+
+static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
+{
+    return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
+            le32_to_cpu(es->s_blocks_count_lo);
+}
+
+static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
+{
+    return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
+            le32_to_cpu(es->s_r_blocks_count_lo);
+}
+
+static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec)
+{
+    /* Check for the types of filesystems we know how to check */
+    if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
+        /*
+         * Some system images do not have tune2fs for licensing reasons
+         * Detect these and skip reserve blocks.
+         */
+        if (access(TUNE2FS_BIN, X_OK)) {
+            ERROR("Not running %s on %s (executable not in system image)\n",
+                  TUNE2FS_BIN, blk_device);
+        } else {
+            INFO("Running %s on %s\n", TUNE2FS_BIN, blk_device);
+
+            int status = 0;
+            int ret = 0;
+            unsigned long reserved_blocks = 0;
+            int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
+            if (fd >= 0) {
+                struct ext4_super_block sb;
+                ret = read_super_block(fd, &sb);
+                if (ret < 0) {
+                    ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno));
+                    goto out;
+                }
+                reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
+                unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
+                if (reserved_threshold < reserved_blocks) {
+                    WARNING("Reserved blocks %lu is too large\n", reserved_blocks);
+                    reserved_blocks = reserved_threshold;
+                }
+
+                if (ext4_r_blocks_count(&sb) == reserved_blocks) {
+                    INFO("Have reserved same blocks\n");
+                    goto out;
+                }
+            } else {
+                ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno));
+                return;
+            }
+
+            char buf[16] = {0};
+            snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks);
+            char *tune2fs_argv[] = {
+                TUNE2FS_BIN,
+                buf,
+                blk_device,
+            };
+
+            ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv,
+                                          &status, true, LOG_KLOG | LOG_FILE,
+                                          true, NULL, NULL, 0);
+
+            if (ret < 0) {
+                /* No need to check for error in fork, we can't really handle it now */
+                ERROR("Failed trying to run %s\n", TUNE2FS_BIN);
+            }
+      out:
+            close(fd);
+        }
+    }
+}
+
 static void remove_trailing_slashes(char *n)
 {
     int len;
@@ -325,6 +421,12 @@
                 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
                          fstab->recs[i].mount_point);
             }
+
+            if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
+                do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
+                                 &fstab->recs[i]);
+            }
+
             if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
                 *attempted_idx = i;
                 mounted = 1;
@@ -690,6 +792,10 @@
                      fstab->recs[i].mount_point);
         }
 
+        if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
+            do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]);
+        }
+
         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
             int rc = fs_mgr_setup_verity(&fstab->recs[i]);
             if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 0bc8bef..f25d10c 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -33,6 +33,7 @@
     int swap_prio;
     int max_comp_streams;
     unsigned int zram_size;
+    uint64_t reserved_size;
     unsigned int file_encryption_mode;
 };
 
@@ -74,6 +75,7 @@
     { "swapprio=",   MF_SWAPPRIO },
     { "zramsize=",   MF_ZRAMSIZE },
     { "max_comp_streams=",   MF_MAX_COMP_STREAMS },
+    { "verifyatboot", MF_VERIFYATBOOT },
     { "verify",      MF_VERIFY },
     { "noemulatedsd", MF_NOEMULATEDSD },
     { "notrim",       MF_NOTRIM },
@@ -81,6 +83,7 @@
     { "slotselect",  MF_SLOTSELECT },
     { "nofail",      MF_NOFAIL },
     { "latemount",   MF_LATEMOUNT },
+    { "reservedsize=", MF_RESERVEDSIZE },
     { "defaults",    0 },
     { 0,             0 },
 };
@@ -107,6 +110,20 @@
     return total;
 }
 
+static uint64_t parse_size(const char *arg)
+{
+    char *endptr;
+    uint64_t size = strtoull(arg, &endptr, 10);
+    if (*endptr == 'k' || *endptr == 'K')
+        size *= 1024LL;
+    else if (*endptr == 'm' || *endptr == 'M')
+        size *= 1024LL * 1024LL;
+    else if (*endptr == 'g' || *endptr == 'G')
+        size *= 1024LL * 1024LL * 1024LL;
+
+    return size;
+}
+
 static int parse_flags(char *flags, struct flag_list *fl,
                        struct fs_mgr_flag_values *flag_vals,
                        char *fs_options, int fs_options_len)
@@ -216,6 +233,11 @@
                         flag_vals->zram_size = calculate_zram_size(val);
                     else
                         flag_vals->zram_size = val;
+                } else if ((fl[i].flag == MF_RESERVEDSIZE) && flag_vals) {
+                    /* The reserved flag is followed by an = and the
+                     * reserved size of the partition.  Get it and return it.
+                     */
+                    flag_vals->reserved_size = parse_size(strchr(p, '=') + 1);
                 }
                 break;
             }
@@ -360,6 +382,7 @@
         fstab->recs[cnt].swap_prio = flag_vals.swap_prio;
         fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams;
         fstab->recs[cnt].zram_size = flag_vals.zram_size;
+        fstab->recs[cnt].reserved_size = flag_vals.reserved_size;
         fstab->recs[cnt].file_encryption_mode = flag_vals.file_encryption_mode;
         cnt++;
     }
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 741f5e9..4632521 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -85,7 +85,9 @@
 #define MF_FORCEFDEORFBE 0x10000
 #define MF_LATEMOUNT    0x20000
 #define MF_NOFAIL       0x40000
+#define MF_VERIFYATBOOT 0x80000
 #define MF_MAX_COMP_STREAMS 0x100000
+#define MF_RESERVEDSIZE 0x200000
 
 #define DM_BUF_SIZE 4096
 
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 031b042..bb61b93 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -32,6 +32,7 @@
 #include <android-base/file.h>
 #include <android-base/strings.h>
 #include <crypto_utils/android_pubkey.h>
+#include <android-base/unique_fd.h>
 #include <cutils/properties.h>
 #include <logwrap/logwrap.h>
 #include <openssl/obj_mac.h>
@@ -73,6 +74,8 @@
 #define VERITY_KMSG_RESTART "dm-verity device corrupted"
 #define VERITY_KMSG_BUFSIZE 1024
 
+#define READ_BUF_SIZE 4096
+
 #define __STRINGIFY(x) #x
 #define STRINGIFY(x) __STRINGIFY(x)
 
@@ -205,6 +208,16 @@
     return 0;
 }
 
+static int destroy_verity_device(struct dm_ioctl *io, char *name, int fd)
+{
+    verity_ioctl_init(io, name, 0);
+    if (ioctl(fd, DM_DEV_REMOVE, io)) {
+        ERROR("Error removing device mapping (%s)", strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
 static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name)
 {
     verity_ioctl_init(io, name, 0);
@@ -606,6 +619,30 @@
     return rc;
 }
 
+static int read_partition(const char *path, uint64_t size)
+{
+    char buf[READ_BUF_SIZE];
+    ssize_t size_read;
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC)));
+
+    if (fd == -1) {
+        ERROR("Failed to open %s: %s\n", path, strerror(errno));
+        return -errno;
+    }
+
+    while (size) {
+        size_read = TEMP_FAILURE_RETRY(read(fd, buf, READ_BUF_SIZE));
+        if (size_read == -1) {
+            ERROR("Error in reading partition %s: %s\n", path,
+                  strerror(errno));
+            return -errno;
+        }
+        size -= size_read;
+    }
+
+    return 0;
+}
+
 static int compare_last_signature(struct fstab_rec *fstab, int *match)
 {
     char tag[METADATA_TAG_MAX_LENGTH + 1];
@@ -788,7 +825,7 @@
     char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
     const char *mount_point;
     char propbuf[PROPERTY_VALUE_MAX];
-    char *status;
+    const char *status;
     int fd = -1;
     int i;
     int mode;
@@ -838,9 +875,13 @@
         verity_ioctl_init(io, mount_point, 0);
 
         if (ioctl(fd, DM_TABLE_STATUS, io)) {
-            ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
-                strerror(errno));
-            continue;
+            if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
+                status = "V";
+            } else {
+                ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
+                      strerror(errno));
+                continue;
+            }
         }
 
         status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
@@ -904,6 +945,7 @@
     alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
     char *mount_point = basename(fstab->mount_point);
+    bool verified_at_boot = false;
 
     if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
             FEC_DEFAULT_ROOTS) < 0) {
@@ -1037,10 +1079,26 @@
     // mark the underlying block device as read-only
     fs_mgr_set_blk_ro(fstab->blk_device);
 
+    // Verify the entire partition in one go
+    // If there is an error, allow it to mount as a normal verity partition.
+    if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) {
+        INFO("Verifying partition %s at boot\n", fstab->blk_device);
+        int err = read_partition(verity_blk_name, verity.data_size);
+        if (!err) {
+            INFO("Verified verity partition %s at boot\n", fstab->blk_device);
+            verified_at_boot = true;
+        }
+    }
+
     // assign the new verity block device as the block device
-    free(fstab->blk_device);
-    fstab->blk_device = verity_blk_name;
-    verity_blk_name = 0;
+    if (!verified_at_boot) {
+        free(fstab->blk_device);
+        fstab->blk_device = verity_blk_name;
+        verity_blk_name = 0;
+    } else if (destroy_verity_device(io, mount_point, fd) < 0) {
+        ERROR("Failed to remove verity device %s\n", mount_point);
+        goto out;
+    }
 
     // make sure we've set everything up properly
     if (test_access(fstab->blk_device) < 0) {
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 9323069..ed22e90 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -75,6 +75,7 @@
     int swap_prio;
     int max_comp_streams;
     unsigned int zram_size;
+    uint64_t reserved_size;
     unsigned int file_encryption_mode;
 };
 
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 7c5e35b..b292725 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -21,6 +21,10 @@
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
+ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true)
+LOCAL_CFLAGS += -DCHARGER_ENABLE_SUSPEND
+LOCAL_SHARED_LIBRARIES += libsuspend
+endif
 LOCAL_SRC_FILES := \
     healthd_mode_android.cpp \
     healthd_mode_charger.cpp \
@@ -90,6 +94,14 @@
 
 LOCAL_C_INCLUDES := bootable/recovery $(LOCAL_PATH)/include
 
+ifneq ($(BOARD_PERIODIC_CHORES_INTERVAL_FAST),)
+LOCAL_CFLAGS += -DBOARD_PERIODIC_CHORES_INTERVAL_FAST=$(BOARD_PERIODIC_CHORES_INTERVAL_FAST)
+endif
+
+ifneq ($(BOARD_PERIODIC_CHORES_INTERVAL_SLOW),)
+LOCAL_CFLAGS += -DBOARD_PERIODIC_CHORES_INTERVAL_SLOW=$(BOARD_PERIODIC_CHORES_INTERVAL_SLOW)
+endif
+
 LOCAL_STATIC_LIBRARIES := \
     libhealthd_internal \
     libbatterymonitor \
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 20a6bf6..aa6735d 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -35,9 +35,19 @@
 
 using namespace android;
 
-// Periodic chores intervals in seconds
-#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
-#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
+#ifndef BOARD_PERIODIC_CHORES_INTERVAL_FAST
+  // Periodic chores fast interval in seconds
+  #define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
+#else
+  #define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (BOARD_PERIODIC_CHORES_INTERVAL_FAST)
+#endif
+
+#ifndef BOARD_PERIODIC_CHORES_INTERVAL_SLOW
+  // Periodic chores fast interval in seconds
+  #define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
+#else
+  #define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (BOARD_PERIODIC_CHORES_INTERVAL_SLOW)
+#endif
 
 static struct healthd_config healthd_config = {
     .periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST,
@@ -143,10 +153,14 @@
     struct android::BatteryProperties* /*props*/) {
 }
 
-int healthd_register_event(int fd, void (*handler)(uint32_t)) {
+int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
     struct epoll_event ev;
 
-    ev.events = EPOLLIN | EPOLLWAKEUP;
+    ev.events = EPOLLIN;
+
+    if (wakeup == EVENT_WAKEUP_FD)
+        ev.events |= EPOLLWAKEUP;
+
     ev.data.ptr = (void *)handler;
     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
         KLOG_ERROR(LOG_TAG,
@@ -252,7 +266,7 @@
     }
 
     fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
-    if (healthd_register_event(uevent_fd, uevent_event))
+    if (healthd_register_event(uevent_fd, uevent_event, EVENT_WAKEUP_FD))
         KLOG_ERROR(LOG_TAG,
                    "register for uevent events failed\n");
 }
@@ -275,7 +289,7 @@
         return;
     }
 
-    if (healthd_register_event(wakealarm_fd, wakealarm_event))
+    if (healthd_register_event(wakealarm_fd, wakealarm_event, EVENT_WAKEUP_FD))
         KLOG_ERROR(LOG_TAG,
                    "Registration of wakealarm event failed\n");
 
@@ -283,17 +297,22 @@
 }
 
 static void healthd_mainloop(void) {
+    int nevents = 0;
     while (1) {
         struct epoll_event events[eventct];
-        int nevents;
         int timeout = awake_poll_interval;
         int mode_timeout;
 
+        /* Don't wait for first timer timeout to run periodic chores */
+        if (!nevents)
+            periodic_chores();
+
+        healthd_mode_ops->heartbeat();
+
         mode_timeout = healthd_mode_ops->preparetowait();
         if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout))
             timeout = mode_timeout;
         nevents = epoll_wait(epollfd, events, eventct, timeout);
-
         if (nevents == -1) {
             if (errno == EINTR)
                 continue;
@@ -305,11 +324,6 @@
             if (events[n].data.ptr)
                 (*(void (*)(int))events[n].data.ptr)(events[n].events);
         }
-
-        if (!nevents)
-            periodic_chores();
-
-        healthd_mode_ops->heartbeat();
     }
 
     return;
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 36c4664..ec3de34 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -341,14 +341,19 @@
 
 static void draw_percent(const animation& anim)
 {
-    if (anim.cur_level <= 0 || anim.cur_status != BATTERY_STATUS_CHARGING) return;
+    int cur_level = anim.cur_level;
+    if (anim.cur_status == BATTERY_STATUS_FULL) {
+        cur_level = 100;
+    }
+
+    if (cur_level <= 0) return;
 
     const animation::text_field& field = anim.text_percent;
     if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) {
         return;
     }
 
-    std::string str = base::StringPrintf("%d%%", anim.cur_level);
+    std::string str = base::StringPrintf("%d%%", cur_level);
 
     int x, y;
     determine_xy(field, str.size(), &x, &y);
@@ -839,7 +844,7 @@
     ret = ev_init(input_callback, charger);
     if (!ret) {
         epollfd = ev_get_epollfd();
-        healthd_register_event(epollfd, charger_event_handler);
+        healthd_register_event(epollfd, charger_event_handler, EVENT_WAKEUP_FD);
     }
 
     struct animation* anim = init_animation();
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index 34ea55f..17efbd6 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -73,9 +73,14 @@
     bool (*screen_on)(android::BatteryProperties *props);
 };
 
+enum EventWakeup {
+    EVENT_NO_WAKEUP_FD,
+    EVENT_WAKEUP_FD,
+};
+
 // Global helper functions
 
-int healthd_register_event(int fd, void (*handler)(uint32_t));
+int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup = EVENT_NO_WAKEUP_FD);
 void healthd_battery_update();
 android::status_t healthd_get_property(int id,
     struct android::BatteryProperty *val);
diff --git a/libsuspend/autosuspend_wakeup_count.c b/libsuspend/autosuspend_wakeup_count.c
index 3457d5b..d3fb45f 100644
--- a/libsuspend/autosuspend_wakeup_count.c
+++ b/libsuspend/autosuspend_wakeup_count.c
@@ -24,7 +24,6 @@
 #include <stddef.h>
 #include <stdbool.h>
 #include <string.h>
-#include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -36,24 +35,12 @@
 #define SYS_POWER_STATE "/sys/power/state"
 #define SYS_POWER_WAKEUP_COUNT "/sys/power/wakeup_count"
 
-#define BASE_SLEEP_TIME 100000
-
 static int state_fd;
 static int wakeup_count_fd;
 static pthread_t suspend_thread;
 static sem_t suspend_lockout;
 static const char *sleep_state = "mem";
 static void (*wakeup_func)(bool success) = NULL;
-static int sleep_time = BASE_SLEEP_TIME;
-
-static void update_sleep_time(bool success) {
-    if (success) {
-        sleep_time = BASE_SLEEP_TIME;
-        return;
-    }
-    // double sleep time after each failure up to one minute
-    sleep_time = MIN(sleep_time * 2, 60000000);
-}
 
 static void *suspend_thread_func(void *arg __attribute__((unused)))
 {
@@ -61,12 +48,10 @@
     char wakeup_count[20];
     int wakeup_count_len;
     int ret;
-    bool success = true;
+    bool success;
 
     while (1) {
-        update_sleep_time(success);
-        usleep(sleep_time);
-        success = false;
+        usleep(100000);
         ALOGV("%s: read wakeup_count\n", __func__);
         lseek(wakeup_count_fd, 0, SEEK_SET);
         wakeup_count_len = TEMP_FAILURE_RETRY(read(wakeup_count_fd, wakeup_count,
@@ -90,6 +75,7 @@
             continue;
         }
 
+        success = true;
         ALOGV("%s: write %*s to wakeup_count\n", __func__, wakeup_count_len, wakeup_count);
         ret = TEMP_FAILURE_RETRY(write(wakeup_count_fd, wakeup_count, wakeup_count_len));
         if (ret < 0) {
@@ -98,8 +84,8 @@
         } else {
             ALOGV("%s: write %s to %s\n", __func__, sleep_state, SYS_POWER_STATE);
             ret = TEMP_FAILURE_RETRY(write(state_fd, sleep_state, strlen(sleep_state)));
-            if (ret >= 0) {
-                success = true;
+            if (ret < 0) {
+                success = false;
             }
             void (*func)(bool success) = wakeup_func;
             if (func != NULL) {