On low power turn off rather than rebooting to allow device to charge
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
This commit is contained in:
parent
cba4ab2aeb
commit
73d7a02dc6
3 changed files with 73 additions and 46 deletions
|
@ -26,6 +26,13 @@ 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;
|
||||
|
@ -33,43 +40,59 @@ namespace
|
|||
|
||||
bool singletonInitialized = false;
|
||||
time_t last_checked = {0};
|
||||
int battery_ok = 1;
|
||||
int last_result = 100;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
singletonInitialized = true;
|
||||
}
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
return last_result >= threshold;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int is_battery_ok()
|
||||
extern "C"
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
if (now == -1 || difftime(now, last_checked) < 5) {
|
||||
return battery_ok;
|
||||
}
|
||||
last_checked = now;
|
||||
|
||||
if (!singletonInitialized) {
|
||||
bs = defaultServiceManager()->checkService(serviceName);
|
||||
if (bs == NULL) {
|
||||
SLOGE("No batteryproperties service!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
interface = interface_cast<IBatteryPropertiesRegistrar>(bs);
|
||||
if (interface == NULL) {
|
||||
SLOGE("No IBatteryPropertiesRegistrar interface");
|
||||
return 1;
|
||||
}
|
||||
|
||||
singletonInitialized = true;
|
||||
int is_battery_ok_to_start()
|
||||
{
|
||||
return is_battery_ok(START_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;
|
||||
int is_battery_ok_to_continue()
|
||||
{
|
||||
return is_battery_ok(CONTINUE_THRESHOLD);
|
||||
}
|
||||
|
||||
return battery_ok;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
27
cryptfs.c
27
cryptfs.c
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue