Skip to content

Commit

Permalink
On low power turn off rather than rebooting to allow device to charge
Browse files Browse the repository at this point in the history
The code was using encrypted_upto == 0 as an indicator that encryption
has succeeded. This meant that if no encryption happened, we would reboot
continually.

We now set encrypted_upto to fs_size when encryption is complete.

Also don't start to encrypt unless we are at 10% power. Stop when we
get to 5% power. This should lead to partial encryptions only very
rarely.

Bug: 15513202
Change-Id: I6214d78579d1fbbe2f63ee8862473d86a89d29b3
  • Loading branch information
PaulLawrenceGoogle committed Jun 9, 2014
1 parent cba4ab2 commit 73d7a02
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 42 deletions.
81 changes: 52 additions & 29 deletions CheckBattery.cpp
Expand Up @@ -26,50 +26,73 @@ namespace
{
// How often to check battery in seconds
const int CHECK_PERIOD = 30;

// How charged should the battery be (percent) to start encrypting
const int START_THRESHOLD = 10;

// How charged should the battery be (percent) to continue encrypting
const int CONTINUE_THRESHOLD = 5;

const String16 serviceName("batteryproperties");

sp<IBinder> bs;
sp<IBatteryPropertiesRegistrar> interface;

bool singletonInitialized = false;
time_t last_checked = {0};
int battery_ok = 1;
}
int last_result = 100;

extern "C" int is_battery_ok()
{
time_t now = time(NULL);
if (now == -1 || difftime(now, last_checked) < 5) {
return battery_ok;
}
last_checked = now;
int is_battery_ok(int threshold)
{
time_t now = time(NULL);
if (now == -1 || difftime(now, last_checked) < 5) {
goto finish;
}
last_checked = now;

if (!singletonInitialized) {
bs = defaultServiceManager()->checkService(serviceName);
if (bs == NULL) {
SLOGE("No batteryproperties service!");
goto finish;
}

interface = interface_cast<IBatteryPropertiesRegistrar>(bs);
if (interface == NULL) {
SLOGE("No IBatteryPropertiesRegistrar interface");
goto finish;
}

if (!singletonInitialized) {
bs = defaultServiceManager()->checkService(serviceName);
if (bs == NULL) {
SLOGE("No batteryproperties service!");
return 1;
singletonInitialized = true;
}

interface = interface_cast<IBatteryPropertiesRegistrar>(bs);
if (interface == NULL) {
SLOGE("No IBatteryPropertiesRegistrar interface");
return 1;
{
BatteryProperty val;
status_t status = interface
->getProperty(android::BATTERY_PROP_CAPACITY, &val);
if (status == NO_ERROR) {
SLOGD("Capacity is %d", (int)val.valueInt64);
last_result = val.valueInt64;
} else {
SLOGE("Failed to get battery charge");
last_result = 100;
}
}

singletonInitialized = true;
finish:
return last_result >= threshold;
}
}

BatteryProperty val;
status_t status = interface->getProperty(android::BATTERY_PROP_CAPACITY,
&val);
if (status == NO_ERROR) {
SLOGD("Capacity is %d", (int)val.valueInt64);
battery_ok = val.valueInt64 > 5 ? 1 : 0;
} else {
SLOGE("Failed to get battery charge");
battery_ok = 1;
extern "C"
{
int is_battery_ok_to_start()
{
return is_battery_ok(START_THRESHOLD);
}

return battery_ok;
int is_battery_ok_to_continue()
{
return is_battery_ok(CONTINUE_THRESHOLD);
}
}
3 changes: 2 additions & 1 deletion CheckBattery.h
Expand Up @@ -21,7 +21,8 @@
extern "C" {
#endif

int is_battery_ok();
int is_battery_ok_to_start();
int is_battery_ok_to_continue();

#ifdef __cplusplus
}
Expand Down
27 changes: 15 additions & 12 deletions cryptfs.c
Expand Up @@ -2049,7 +2049,7 @@ static int encrypt_groups(struct encryptGroupsData* data)
}
}

if (!is_battery_ok()) {
if (!is_battery_ok_to_continue()) {
SLOGE("Stopping encryption due to low battery");
rc = 0;
goto errout;
Expand Down Expand Up @@ -2231,7 +2231,7 @@ static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev,
i * CRYPT_SECTORS_PER_BUFSIZE);
}

if (!is_battery_ok()) {
if (!is_battery_ok_to_continue()) {
SLOGE("Stopping encryption due to low battery");
*size_already_done += (i + 1) * CRYPT_SECTORS_PER_BUFSIZE - 1;
rc = 0;
Expand Down Expand Up @@ -2332,8 +2332,8 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
off64_t cur_encryption_done=0, tot_encryption_size=0;
int i, rc = -1;

if (!is_battery_ok()) {
SLOGE("Stopping encryption due to low battery");
if (!is_battery_ok_to_start()) {
SLOGW("Not starting encryption due to low battery");
return 0;
}

Expand All @@ -2348,11 +2348,11 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
tot_encryption_size,
previously_encrypted_upto);

if (!rc && cur_encryption_done != (off64_t)crypt_ftr->fs_size) {
if (!rc) {
crypt_ftr->encrypted_upto = cur_encryption_done;
}

if (!rc && !crypt_ftr->encrypted_upto) {
if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) {
/* The inplace routine never actually sets the progress to 100% due
* to the round down nature of integer division, so set it here */
property_set("vold.encrypt_progress", "100");
Expand Down Expand Up @@ -2601,10 +2601,10 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
}

/* Calculate checksum if we are not finished */
if (!rc && crypt_ftr.encrypted_upto) {
if (!rc && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
rc = cryptfs_SHA256_fileblock(crypto_blkdev,
crypt_ftr.hash_first_block);
if (!rc) {
if (rc) {
SLOGE("Error calculating checksum for continuing encryption");
rc = -1;
}
Expand All @@ -2618,19 +2618,22 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
if (! rc) {
/* Success */

/* Clear the encryption in progres flag in the footer */
if (!crypt_ftr.encrypted_upto) {
/* Clear the encryption in progress flag in the footer */
if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
} else {
SLOGD("Encrypted up to sector %lld - will continue after reboot",
crypt_ftr.encrypted_upto);
}
put_crypt_ftr_and_key(&crypt_ftr);

if (crypt_ftr.encrypted_upto) {
put_crypt_ftr_and_key(&crypt_ftr);
}

sleep(2); /* Give the UI a chance to show 100% progress */
/* Partially encrypted - ensure writes are flushed to ssd */

if (!crypt_ftr.encrypted_upto) {
if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
cryptfs_reboot(reboot);
} else {
cryptfs_reboot(shutdown);
Expand Down

0 comments on commit 73d7a02

Please sign in to comment.