summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext4_utils/Android.mk2
-rw-r--r--ext4_utils/e4crypt_static.c147
-rw-r--r--ext4_utils/ext4_crypt.cpp181
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.cpp186
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.h15
-rw-r--r--ext4_utils/key_control.cpp44
-rw-r--r--ext4_utils/key_control.h (renamed from ext4_utils/ext4_crypt.h)25
-rw-r--r--ext4_utils/make_ext4fs.c1
-rw-r--r--ext4_utils/make_ext4fs_main.c2
-rw-r--r--ext4_utils/unencrypted_properties.cpp32
-rw-r--r--ext4_utils/unencrypted_properties.h24
-rw-r--r--f2fs_utils/f2fs_ioutils.c1
-rw-r--r--perfprofd/perf_profile.proto10
-rw-r--r--perfprofd/perfprofdcore.cc78
-rw-r--r--perfprofd/perfprofdcore.h3
-rw-r--r--perfprofd/tests/perfprofd_test.cc3
-rwxr-xr-xtests/workloads/capture.sh22
-rwxr-xr-xtests/workloads/defs.sh82
-rwxr-xr-xtests/workloads/recentfling.sh64
-rwxr-xr-xtests/workloads/systemapps.sh134
-rw-r--r--verity/Android.mk2
21 files changed, 506 insertions, 552 deletions
diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk
index 08088863..31a4b711 100644
--- a/ext4_utils/Android.mk
+++ b/ext4_utils/Android.mk
@@ -53,8 +53,8 @@ include $(BUILD_HOST_EXECUTABLE)
#
libext4_utils_src_files += \
+ key_control.cpp \
ext4_crypt.cpp \
- e4crypt_static.c \
unencrypted_properties.cpp
ifneq ($(HOST_OS),windows)
diff --git a/ext4_utils/e4crypt_static.c b/ext4_utils/e4crypt_static.c
deleted file mode 100644
index 1a62ce4a..00000000
--- a/ext4_utils/e4crypt_static.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc.
- */
-
-#define TAG "ext4_utils"
-
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/xattr.h>
-#include <sys/syscall.h>
-#include <sys/stat.h>
-
-#include <cutils/klog.h>
-
-#include "ext4_crypt.h"
-
-/* keyring keyctl commands */
-#define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */
-#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
-#define KEYCTL_SEARCH 10 /* search for a key in a keyring */
-
-#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
-#define EXT4_KEYREF_DELIMITER ((char)'.')
-
-/* Validate that all path items are available and accessible. */
-static int is_path_valid(const char *path)
-{
- if (access(path, W_OK)) {
- KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path);
- return 0;
- }
-
- return 1;
-}
-
-/* Checks whether the policy provided is valid */
-static int is_keyref_valid(const char *keyref)
-{
- char *period = 0;
- size_t key_location_len = 0;
-
- /* Key ref must have a key and location delimiter character. */
- period = strchr(keyref, EXT4_KEYREF_DELIMITER);
- if (!period) {
- return 0;
- }
-
- /* period must be >= keyref. */
- key_location_len = period - keyref;
-
- if (strncmp(keyref, "@t", key_location_len) == 0 ||
- strncmp(keyref, "@p", key_location_len) == 0 ||
- strncmp(keyref, "@s", key_location_len) == 0 ||
- strncmp(keyref, "@u", key_location_len) == 0 ||
- strncmp(keyref, "@g", key_location_len) == 0 ||
- strncmp(keyref, "@us", key_location_len) == 0)
- return 1;
-
- return 0;
-}
-
-static int is_dir_empty(const char *dirname)
-{
- int n = 0;
- struct dirent *d;
- DIR *dir;
-
- dir = opendir(dirname);
- while ((d = readdir(dir)) != NULL) {
- if (strcmp(d->d_name, "lost+found") == 0) {
- // Skip lost+found directory
- } else if (++n > 2) {
- break;
- }
- }
- closedir(dir);
- return n <= 2;
-}
-
-int do_policy_set(const char *directory, const char *policy)
-{
- struct stat st;
- ssize_t ret;
-
- if (!is_keyref_valid(policy)) {
- KLOG_ERROR(TAG, "Policy has invalid format.\n");
- return -EINVAL;
- }
-
- if (!is_path_valid(directory)) {
- return -EINVAL;
- }
-
- stat(directory, &st);
- if (!S_ISDIR(st.st_mode)) {
- KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory);
- return -EINVAL;
- }
-
- if (!is_dir_empty(directory)) {
- KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n", directory);
- return -EINVAL;
- }
-
- ret = lsetxattr(directory, XATTR_NAME_ENCRYPTION_POLICY, policy,
- strlen(policy), 0);
-
- if (ret) {
- KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n",
- directory, strerror(errno));
- return -EINVAL;
- }
-
- KLOG_INFO(TAG, "Encryption policy for %s is set to %s\n", directory, policy);
- return 0;
-}
-
-static long keyctl(int cmd, ...)
-{
- va_list va;
- unsigned long arg2, arg3, arg4, arg5;
-
- va_start(va, cmd);
- arg2 = va_arg(va, unsigned long);
- arg3 = va_arg(va, unsigned long);
- arg4 = va_arg(va, unsigned long);
- arg5 = va_arg(va, unsigned long);
- va_end(va);
- return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
-}
-
-key_serial_t add_key(const char *type,
- const char *description,
- const void *payload,
- size_t plen,
- key_serial_t ringid)
-{
- return syscall(__NR_add_key, type, description, payload, plen, ringid);
-}
-
-long keyctl_setperm(key_serial_t id, int permissions)
-{
- return keyctl(KEYCTL_SETPERM, id, permissions);
-}
diff --git a/ext4_utils/ext4_crypt.cpp b/ext4_utils/ext4_crypt.cpp
index bb573323..886d17a1 100644
--- a/ext4_utils/ext4_crypt.cpp
+++ b/ext4_utils/ext4_crypt.cpp
@@ -1,120 +1,131 @@
-#define TAG "ext4_utils"
+/*
+ * Copyright (c) 2015 Google, Inc.
+ */
-#include "ext4_crypt.h"
+#define TAG "ext4_utils"
-#include <string>
-#include <fstream>
-#include <map>
+#include "ext4_crypt_init_extensions.h"
+#include <dirent.h>
#include <errno.h>
-#include <sys/mount.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <asm/ioctl.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <cutils/klog.h>
-#include <cutils/properties.h>
#include "unencrypted_properties.h"
-namespace {
- std::map<std::string, std::string> s_password_store;
-}
-
-bool e4crypt_non_default_key(const char* dir)
+#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
+#define EXT4_KEYREF_DELIMITER ((char)'.')
+
+// ext4enc:TODO Include structure from somewhere sensible
+// MUST be in sync with ext4_crypto.c in kernel
+#define EXT4_KEY_DESCRIPTOR_SIZE 8
+struct ext4_encryption_policy {
+ char version;
+ char contents_encryption_mode;
+ char filenames_encryption_mode;
+ char flags;
+ char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
+} __attribute__((__packed__));
+
+#define EXT4_ENCRYPTION_MODE_AES_256_XTS 1
+#define EXT4_ENCRYPTION_MODE_AES_256_CTS 4
+
+// ext4enc:TODO Get value from somewhere sensible
+#define EXT4_IOC_SET_ENCRYPTION_POLICY \
+ _IOR('f', 19, struct ext4_encryption_policy)
+
+/* Validate that all path items are available and accessible. */
+static int is_path_valid(const char *path)
{
- int type = e4crypt_get_password_type(dir);
+ if (access(path, W_OK)) {
+ KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path);
+ return 0;
+ }
- // ext4enc:TODO Use consts, not 1 here
- return type != -1 && type != 1;
+ return 1;
}
-int e4crypt_get_password_type(const char* path)
+static int is_dir_empty(const char *dirname)
{
- UnencryptedProperties props(path);
- if (props.Get<std::string>(properties::key).empty()) {
- KLOG_INFO(TAG, "No master key, so not ext4enc\n");
- return -1;
+ int n = 0;
+ struct dirent *d;
+ DIR *dir;
+
+ dir = opendir(dirname);
+ while ((d = readdir(dir)) != NULL) {
+ if (strcmp(d->d_name, "lost+found") == 0) {
+ // Skip lost+found directory
+ } else if (++n > 2) {
+ break;
+ }
}
-
- return props.Get<int>(properties::type, 1);
+ closedir(dir);
+ return n <= 2;
}
-int e4crypt_change_password(const char* path, int crypt_type,
- const char* password)
+int do_policy_set(const char *directory, const char *policy, int policy_length)
{
- // ext4enc:TODO Encrypt master key with password securely. Store hash of
- // master key for validation
- UnencryptedProperties props(path);
- if ( props.Set(properties::password, password)
- && props.Set(properties::type, crypt_type))
- return 0;
- return -1;
-}
+ struct stat st;
+ ssize_t ret;
-int e4crypt_crypto_complete(const char* path)
-{
- KLOG_INFO(TAG, "ext4 crypto complete called on %s\n", path);
- if (UnencryptedProperties(path).Get<std::string>(properties::key).empty()) {
- KLOG_INFO(TAG, "No master key, so not ext4enc\n");
- return -1;
+ if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) {
+ KLOG_ERROR("Policy wrong length\n");
+ return -EINVAL;
}
- return 0;
-}
-
-int e4crypt_check_passwd(const char* path, const char* password)
-{
- UnencryptedProperties props(path);
- if (props.Get<std::string>(properties::key).empty()) {
- KLOG_INFO(TAG, "No master key, so not ext4enc\n");
- return -1;
+ if (!is_path_valid(directory)) {
+ return -EINVAL;
}
- auto actual_password = props.Get<std::string>(properties::password);
-
- if (actual_password == password) {
- s_password_store[path] = password;
- return 0;
- } else {
- return -1;
+ stat(directory, &st);
+ if (!S_ISDIR(st.st_mode)) {
+ KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory);
+ return -EINVAL;
}
-}
-int e4crypt_restart(const char* path)
-{
- int rc = 0;
-
- KLOG_INFO(TAG, "ext4 restart called on %s\n", path);
- property_set("vold.decrypt", "trigger_reset_main");
- KLOG_INFO(TAG, "Just asked init to shut down class main\n");
- sleep(2);
-
- std::string tmp_path = std::string() + path + "/tmp_mnt";
+ if (!is_dir_empty(directory)) {
+ KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n",
+ directory);
+ return -EINVAL;
+ }
- // ext4enc:TODO add retry logic
- rc = umount(tmp_path.c_str());
- if (rc) {
- KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
- tmp_path.c_str(), rc, strerror(errno));
- return rc;
+ int fd = open(directory, O_DIRECTORY);
+ if (fd == -1) {
+ KLOG_ERROR(TAG, "Failed to open directory (%s)\n", directory);
+ return -EINVAL;
}
- // ext4enc:TODO add retry logic
- rc = umount(path);
- if (rc) {
- KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
- path, rc, strerror(errno));
- return rc;
+ ext4_encryption_policy eep;
+ eep.version = 0;
+ eep.contents_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
+ eep.filenames_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS;
+ eep.flags = 0;
+ memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE);
+ ret = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep);
+ auto preserve_errno = errno;
+ close(fd);
+
+ if (ret) {
+ KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n",
+ directory, strerror(preserve_errno));
+ return -EINVAL;
}
+ KLOG_INFO(TAG, "Encryption policy for %s is set to %02x%02x%02x%02x\n",
+ directory, policy[0], policy[1], policy[2], policy[3]);
return 0;
}
-const char* e4crypt_get_password(const char* path)
+bool e4crypt_non_default_key(const char* dir)
{
- // ext4enc:TODO scrub password after timeout
- auto i = s_password_store.find(path);
- if (i == s_password_store.end()) {
- return 0;
- } else {
- return i->second.c_str();
- }
+ UnencryptedProperties props(dir);
+ return props.Get<int>(properties::is_default, 1) != 1;
}
diff --git a/ext4_utils/ext4_crypt_init_extensions.cpp b/ext4_utils/ext4_crypt_init_extensions.cpp
index 284437f9..3fb04b98 100644
--- a/ext4_utils/ext4_crypt_init_extensions.cpp
+++ b/ext4_utils/ext4_crypt_init_extensions.cpp
@@ -1,12 +1,10 @@
#define TAG "ext4_utils"
-#include "ext4_crypt.h"
+#include "ext4_crypt_init_extensions.h"
#include <string>
-#include <fstream>
-#include <iomanip>
-#include <sstream>
+#include <dirent.h>
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
@@ -16,29 +14,26 @@
#include <cutils/sockets.h>
#include <poll.h>
+#include "key_control.h"
#include "unencrypted_properties.h"
-// ext4enc:TODO Include structure from somewhere sensible
-// MUST be in sync with ext4_crypto.c in kernel
-#define EXT4_MAX_KEY_SIZE 76
-struct ext4_encryption_key {
- uint32_t mode;
- char raw[EXT4_MAX_KEY_SIZE];
- uint32_t size;
-};
-
-static const std::string keyring = "@s";
static const std::string arbitrary_sequence_number = "42";
-static const int vold_command_timeout_ms = 10 * 1000;
-
-static key_serial_t device_keyring = -1;
+static const int vold_command_timeout_ms = 60 * 1000;
static std::string vold_command(std::string const& command)
{
KLOG_INFO(TAG, "Running command %s\n", command.c_str());
- int sock = socket_local_client("vold",
+ int sock = -1;
+
+ while (true) {
+ sock = socket_local_client("cryptd",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
+ if (sock >= 0) {
+ break;
+ }
+ usleep(10000);
+ }
if (sock < 0) {
KLOG_INFO(TAG, "Cannot open vold, failing command\n");
@@ -65,18 +60,19 @@ static std::string vold_command(std::string const& command)
struct pollfd poll_sock = {sock, POLLIN, 0};
- int rc = poll(&poll_sock, 1, vold_command_timeout_ms);
+ int rc = TEMP_FAILURE_RETRY(poll(&poll_sock, 1, vold_command_timeout_ms));
if (rc < 0) {
KLOG_ERROR(TAG, "Error in poll %s\n", strerror(errno));
return "";
}
+
if (!(poll_sock.revents & POLLIN)) {
KLOG_ERROR(TAG, "Timeout\n");
return "";
}
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
- rc = read(sock, buffer, sizeof(buffer));
+ rc = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
if (rc <= 0) {
if (rc == 0) {
KLOG_ERROR(TAG, "Lost connection to Vold - did it crash?\n");
@@ -97,52 +93,34 @@ static std::string vold_command(std::string const& command)
int e4crypt_create_device_key(const char* dir,
int ensure_dir_exists(const char*))
{
+ // Already encrypted with password? If so bail
+ std::string temp_folder = std::string() + dir + "/tmp_mnt";
+ DIR* temp_dir = opendir(temp_folder.c_str());
+ if (temp_dir) {
+ closedir(temp_dir);
+ return 0;
+ }
+
// Make sure folder exists. Use make_dir to set selinux permissions.
- KLOG_INFO(TAG, "Creating test device key\n");
- UnencryptedProperties props(dir);
- if (ensure_dir_exists(props.GetPath().c_str())) {
+ if (ensure_dir_exists(UnencryptedProperties::GetPath(dir).c_str())) {
KLOG_ERROR(TAG, "Failed to create %s with error %s\n",
- props.GetPath().c_str(), strerror(errno));
+ UnencryptedProperties::GetPath(dir).c_str(),
+ strerror(errno));
return -1;
}
- if (props.Get<std::string>(properties::key).empty()) {
- // Create new key since it doesn't already exist
- std::ifstream urandom("/dev/urandom", std::ifstream::binary);
- if (!urandom) {
- KLOG_ERROR(TAG, "Failed to open /dev/urandom\n");
- return -1;
- }
-
- // ext4enc:TODO Don't hardcode 32
- std::string key_material(32, '\0');
- urandom.read(&key_material[0], key_material.length());
- if (!urandom) {
- KLOG_ERROR(TAG, "Failed to read random bytes\n");
- return -1;
- }
-
- if (!props.Set(properties::key, key_material)) {
- KLOG_ERROR(TAG, "Failed to write key material\n");
- return -1;
- }
- }
-
- if (!props.Remove(properties::ref)) {
- KLOG_ERROR(TAG, "Failed to remove key ref\n");
- return -1;
- }
+ auto result = vold_command("cryptfs enablefilecrypto");
+ // ext4enc:TODO proper error handling
+ KLOG_INFO(TAG, "enablefilecrypto returned with result %s\n",
+ result.c_str());
return 0;
}
int e4crypt_install_keyring()
{
- device_keyring = add_key("keyring",
- "e4crypt",
- 0,
- 0,
- KEY_SPEC_SESSION_KEYRING);
+ key_serial_t device_keyring = add_key("keyring", "e4crypt", 0, 0,
+ KEY_SPEC_SESSION_KEYRING);
if (device_keyring == -1) {
KLOG_ERROR(TAG, "Failed to create keyring\n");
@@ -152,90 +130,6 @@ int e4crypt_install_keyring()
KLOG_INFO(TAG, "Keyring created wth id %d in process %d\n",
device_keyring, getpid());
- // ext4enc:TODO set correct permissions
- long result = keyctl_setperm(device_keyring, 0x3f3f3f3f);
- if (result) {
- KLOG_ERROR(TAG, "KEYCTL_SETPERM failed with error %ld\n", result);
- return -1;
- }
-
- return 0;
-}
-
-int e4crypt_install_key(const char* dir)
-{
- UnencryptedProperties props(dir);
- auto key = props.Get<std::string>(properties::key);
-
- // Get password to decrypt as needed
- if (e4crypt_non_default_key(dir)) {
- std::string result = vold_command("cryptfs getpw");
- // result is either
- // 200 0 -1
- // or
- // 200 0 {{sensitive}} 0001020304
- // where 0001020304 is hex encoding of password
- std::istringstream i(result);
- std::string bit;
- i >> bit;
- if (bit != "200") {
- KLOG_ERROR(TAG, "Expecting 200\n");
- return -1;
- }
-
- i >> bit;
- if (bit != arbitrary_sequence_number) {
- KLOG_ERROR(TAG, "Expecting %s\n", arbitrary_sequence_number.c_str());
- return -1;
- }
-
- i >> bit;
- if (bit != "{{sensitive}}") {
- KLOG_INFO(TAG, "Not encrypted\n");
- return -1;
- }
-
- i >> bit;
- }
-
- // Add key to keyring
- ext4_encryption_key ext4_key = {0, {0}, 0};
- if (key.length() > sizeof(ext4_key.raw)) {
- KLOG_ERROR(TAG, "Key too long\n");
- return -1;
- }
-
- ext4_key.mode = 0;
- memcpy(ext4_key.raw, &key[0], key.length());
- ext4_key.size = key.length();
-
- // ext4enc:TODO Use better reference not 1234567890
- key_serial_t key_id = add_key("logon", "ext4-key:1234567890",
- (void*)&ext4_key, sizeof(ext4_key),
- device_keyring);
-
- if (key_id == -1) {
- KLOG_ERROR(TAG, "Failed to insert key into keyring with error %s\n",
- strerror(errno));
- return -1;
- }
-
- KLOG_INFO(TAG, "Added key %d to keyring %d in process %d\n",
- key_id, device_keyring, getpid());
-
- // ext4enc:TODO set correct permissions
- long result = keyctl_setperm(key_id, 0x3f3f3f3f);
- if (result) {
- KLOG_ERROR(TAG, "KEYCTL_SETPERM failed with error %ld\n", result);
- return -1;
- }
-
- // Save reference to key so we can set policy later
- if (!props.Set(properties::ref, "ext4-key:1234567890")) {
- KLOG_ERROR(TAG, "Cannot save key reference\n");
- return -1;
- }
-
return 0;
}
@@ -250,12 +144,16 @@ int e4crypt_set_directory_policy(const char* dir)
}
UnencryptedProperties props("/data");
- std::string ref = props.Get<std::string>(properties::ref);
- std::string policy = keyring + "." + ref;
- KLOG_INFO(TAG, "Setting policy %s\n", policy.c_str());
- int result = do_policy_set(dir, policy.c_str());
+ std::string policy = props.Get<std::string>(properties::ref);
+ if (policy.empty()) {
+ return 0;
+ }
+
+ KLOG_INFO(TAG, "Setting policy on %s\n", dir);
+ int result = do_policy_set(dir, policy.c_str(), policy.size());
if (result) {
- KLOG_ERROR(TAG, "Setting policy on %s failed!\n", dir);
+ KLOG_ERROR(TAG, "Setting %s policy on %s failed!\n",
+ policy.c_str(), dir);
return -1;
}
diff --git a/ext4_utils/ext4_crypt_init_extensions.h b/ext4_utils/ext4_crypt_init_extensions.h
new file mode 100644
index 00000000..79311246
--- /dev/null
+++ b/ext4_utils/ext4_crypt_init_extensions.h
@@ -0,0 +1,15 @@
+#include <sys/cdefs.h>
+#include <stdbool.h>
+
+__BEGIN_DECLS
+
+// These functions assume they are being called from init
+// They will not operate properly outside of init
+int e4crypt_install_keyring();
+int e4crypt_create_device_key(const char* path,
+ int ensure_dir_exists(const char* dir));
+int e4crypt_set_directory_policy(const char* path);
+bool e4crypt_non_default_key(const char* path);
+int do_policy_set(const char *directory, const char *policy, int policy_length);
+
+__END_DECLS
diff --git a/ext4_utils/key_control.cpp b/ext4_utils/key_control.cpp
new file mode 100644
index 00000000..3d775b7f
--- /dev/null
+++ b/ext4_utils/key_control.cpp
@@ -0,0 +1,44 @@
+#include "key_control.h"
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/* keyring keyctl commands */
+#define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */
+#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
+#define KEYCTL_SEARCH 10 /* search for a key in a keyring */
+
+static long keyctl(int cmd, ...)
+{
+ va_list va;
+ unsigned long arg2, arg3, arg4, arg5;
+
+ va_start(va, cmd);
+ arg2 = va_arg(va, unsigned long);
+ arg3 = va_arg(va, unsigned long);
+ arg4 = va_arg(va, unsigned long);
+ arg5 = va_arg(va, unsigned long);
+ va_end(va);
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+}
+
+key_serial_t add_key(const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_serial_t ringid)
+{
+ return syscall(__NR_add_key, type, description, payload, plen, ringid);
+}
+
+long keyctl_setperm(key_serial_t id, int permissions)
+{
+ return keyctl(KEYCTL_SETPERM, id, permissions);
+}
+
+long keyctl_search(key_serial_t ringid, const char *type,
+ const char *description, key_serial_t destringid)
+{
+ return keyctl(KEYCTL_SEARCH, ringid, type, description, destringid);
+}
diff --git a/ext4_utils/ext4_crypt.h b/ext4_utils/key_control.h
index cc692735..8e6e32ba 100644
--- a/ext4_utils/ext4_crypt.h
+++ b/ext4_utils/key_control.h
@@ -1,28 +1,7 @@
-#include <stdbool.h>
#include <sys/cdefs.h>
#include <sys/types.h>
__BEGIN_DECLS
-// These functions assume they are being called from init
-// They will not operate properly outside of init
-int e4crypt_install_keyring();
-int e4crypt_install_key(const char* dir);
-int e4crypt_create_device_key(const char* dir,
- int ensure_dir_exists(const char* dir));
-
-// General functions
-bool e4crypt_non_default_key(const char* dir);
-int e4crypt_set_directory_policy(const char* dir);
-int e4crypt_main(int argc, char* argv[]);
-int e4crypt_change_password(const char* path, int crypt_type,
- const char* password);
-int e4crypt_get_password_type(const char* path);
-int e4crypt_crypto_complete(const char* dir);
-int e4crypt_check_passwd(const char* dir, const char* password);
-const char* e4crypt_get_password(const char* dir);
-int e4crypt_restart(const char* dir);
-
-// Key functions. ext4enc:TODO Move to own file
// ext4enc:TODO - get these keyring standard definitions from proper system file
// keyring serial number type
@@ -44,7 +23,7 @@ key_serial_t add_key(const char *type,
long keyctl_setperm(key_serial_t id, int permissions);
-// Set policy on directory
-int do_policy_set(const char *directory, const char *policy);
+long keyctl_search(key_serial_t ringid, const char *type,
+ const char *description, key_serial_t destringid);
__END_DECLS
diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c
index 5c9e2085..c089d255 100644
--- a/ext4_utils/make_ext4fs.c
+++ b/ext4_utils/make_ext4fs.c
@@ -61,7 +61,6 @@
#include <selinux/selinux.h>
#include <selinux/label.h>
-#include <selinux/android.h>
#define O_BINARY 0
diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c
index 0e2ef5e5..f28e1b22 100644
--- a/ext4_utils/make_ext4fs_main.c
+++ b/ext4_utils/make_ext4fs_main.c
@@ -32,7 +32,9 @@
#ifndef USE_MINGW
#include <selinux/selinux.h>
#include <selinux/label.h>
+#if !defined(HOST)
#include <selinux/android.h>
+#endif
#else
struct selabel_handle;
#endif
diff --git a/ext4_utils/unencrypted_properties.cpp b/ext4_utils/unencrypted_properties.cpp
index bef7c57b..d873e91f 100644
--- a/ext4_utils/unencrypted_properties.cpp
+++ b/ext4_utils/unencrypted_properties.cpp
@@ -1,12 +1,13 @@
#include "unencrypted_properties.h"
#include <sys/stat.h>
+#include <dirent.h>
namespace properties {
const char* key = "key";
const char* ref = "ref";
- const char* type = "type";
- const char* password = "password";
+ const char* props = "props";
+ const char* is_default = "is_default";
}
namespace
@@ -14,9 +15,20 @@ namespace
const char* unencrypted_folder = "unencrypted";
}
+std::string UnencryptedProperties::GetPath(const char* device)
+{
+ return std::string() + device + "/" + unencrypted_folder;
+}
+
UnencryptedProperties::UnencryptedProperties(const char* device)
- : folder_(std::string() + device + "/" + unencrypted_folder)
+ : folder_(GetPath(device))
{
+ DIR* dir = opendir(folder_.c_str());
+ if (dir) {
+ closedir(dir);
+ } else {
+ folder_.clear();
+ }
}
UnencryptedProperties::UnencryptedProperties()
@@ -24,7 +36,7 @@ UnencryptedProperties::UnencryptedProperties()
}
template<> std::string UnencryptedProperties::Get(const char* name,
- std::string default_value)
+ std::string default_value) const
{
if (!OK()) return default_value;
std::ifstream i(folder_ + "/" + name, std::ios::binary);
@@ -56,18 +68,18 @@ template<> bool UnencryptedProperties::Set(const char* name, std::string const&
return !o.fail();
}
-UnencryptedProperties UnencryptedProperties::GetChild(const char* name)
+UnencryptedProperties UnencryptedProperties::GetChild(const char* name) const
{
- UnencryptedProperties e4p;
- if (!OK()) return e4p;
+ UnencryptedProperties up;
+ if (!OK()) return up;
std::string directory(folder_ + "/" + name);
if (mkdir(directory.c_str(), 700) == -1 && errno != EEXIST) {
- return e4p;
+ return up;
}
- e4p.folder_ = directory;
- return e4p;
+ up.folder_ = directory;
+ return up;
}
bool UnencryptedProperties::Remove(const char* name)
diff --git a/ext4_utils/unencrypted_properties.h b/ext4_utils/unencrypted_properties.h
index 80f41df4..b2d1295f 100644
--- a/ext4_utils/unencrypted_properties.h
+++ b/ext4_utils/unencrypted_properties.h
@@ -5,8 +5,8 @@
namespace properties {
extern const char* key;
extern const char* ref;
- extern const char* type;
- extern const char* password;
+ extern const char* props;
+ extern const char* is_default;
}
/**
@@ -18,34 +18,38 @@ namespace properties {
class UnencryptedProperties
{
public:
+ // Get path of folder. Must create before using any properties
+ // This is to allow proper setting of SELinux policy
+ static std::string GetPath(const char* device);
+
// Opens properties folder on named device.
- // If folder does not exist, construction will succeed, but all
+ // If folder does not exist, OK will return false, all
// getters will return default properties and setters will fail.
UnencryptedProperties(const char* device);
// Get named object. Return default if object does not exist or error.
- template<typename t> t Get(const char* name, t default_value = t());
+ template<typename t> t Get(const char* name, t default_value = t()) const;
// Set named object. Return true if success, false otherwise
template<typename t> bool Set(const char* name, t const& value);
// Get child properties
- UnencryptedProperties GetChild(const char* name);
+ UnencryptedProperties GetChild(const char* name) const;
// Remove named object
bool Remove(const char* name);
- // Get path of folder
- std::string const& GetPath() const {return folder_;}
+ // Does folder exist?
+ bool OK() const;
+
private:
UnencryptedProperties();
- bool OK() const;
std::string folder_;
};
template<typename t> t UnencryptedProperties::Get(const char* name,
- t default_value)
+ t default_value) const
{
if (!OK()) return default_value;
t value = default_value;
@@ -64,7 +68,7 @@ template<typename t> bool UnencryptedProperties::Set(const char* name,
// Specialized getters/setters for strings
template<> std::string UnencryptedProperties::Get(const char* name,
- std::string default_value);
+ std::string default_value) const;
template<> bool UnencryptedProperties::Set(const char* name,
std::string const& value);
diff --git a/f2fs_utils/f2fs_ioutils.c b/f2fs_utils/f2fs_ioutils.c
index f3b2a638..a050cf8f 100644
--- a/f2fs_utils/f2fs_ioutils.c
+++ b/f2fs_utils/f2fs_ioutils.c
@@ -78,7 +78,6 @@ struct selabel_handle;
#include <selinux/selinux.h>
#include <selinux/label.h>
-#include <selinux/android.h>
#define O_BINARY 0
diff --git a/perfprofd/perf_profile.proto b/perfprofd/perf_profile.proto
index ee34163f..3932a162 100644
--- a/perfprofd/perf_profile.proto
+++ b/perfprofd/perf_profile.proto
@@ -91,4 +91,12 @@ message AndroidPerfProfile {
// List of all load modules.
repeated LoadModule load_modules = 4;
-} \ No newline at end of file
+
+ // is device screen on at point when profile is collected?
+ optional bool display_on = 5;
+
+ // system load at point when profile is collected; corresponds
+ // to first value from /proc/loadavg multiplied by 100 then
+ // converted to int32
+ optional int32 sys_load_average = 6;
+}
diff --git a/perfprofd/perfprofdcore.cc b/perfprofd/perfprofdcore.cc
index b5f1872b..8f5b013c 100644
--- a/perfprofd/perfprofdcore.cc
+++ b/perfprofd/perfprofdcore.cc
@@ -34,6 +34,7 @@
#include <set>
#include <cctype>
+#include <base/file.h>
#include <base/stringprintf.h>
#include <cutils/properties.h>
@@ -106,11 +107,6 @@ static const char *config_file_path =
"/data/data/com.google.android.gms/files/perfprofd.conf";
//
-// Set by SIGHUP signal handler
-//
-volatile unsigned please_reread_config_file = 0;
-
-//
// This table describes the config file syntax in terms of key/value pairs.
// Values come in two flavors: strings, or unsigned integers. In the latter
// case the reader sets allowable minimum/maximum for the setting.
@@ -126,7 +122,7 @@ class ConfigReader {
std::string getStringValue(const char *key) const;
// read the specified config file, applying any settings it contains
- void readFile();
+ void readFile(bool initial);
private:
void addUnsignedEntry(const char *key,
@@ -163,7 +159,7 @@ void ConfigReader::addDefaultEntries()
// set to 100, then over time we want to see a perf profile
// collected every 100 seconds). The actual time within the interval
// for the collection is chosen randomly.
- addUnsignedEntry("collection_interval", 901, 100, UINT32_MAX);
+ addUnsignedEntry("collection_interval", 14400, 100, UINT32_MAX);
// Use the specified fixed seed for random number generation (unit
// testing)
@@ -205,6 +201,11 @@ void ConfigReader::addDefaultEntries()
addUnsignedEntry("hardwire_cpus", 1, 0, 1);
addUnsignedEntry("hardwire_cpus_max_duration", 5, 1, UINT32_MAX);
+ // Maximum number of unprocessed profiles we can accumulate in the
+ // destination directory. Once we reach this limit, we continue
+ // to collect, but we just overwrite the most recent profile.
+ addUnsignedEntry("max_unprocessed_profiles", 10, 1, UINT32_MAX);
+
// If set to 1, pass the -g option when invoking 'perf' (requests
// stack traces as opposed to flat profile).
addUnsignedEntry("stack_profile", 0, 0, 1);
@@ -323,11 +324,13 @@ static bool isblank(const std::string &line)
return true;
}
-void ConfigReader::readFile()
+void ConfigReader::readFile(bool initial)
{
FILE *fp = fopen(config_file_path, "r");
if (!fp) {
- W_ALOGE("unable to open configuration file %s", config_file_path);
+ if (initial) {
+ W_ALOGE("unable to open configuration file %s", config_file_path);
+ }
return;
}
@@ -479,6 +482,35 @@ static CKPROFILE_RESULT check_profiling_enabled(ConfigReader &config)
return DO_COLLECT_PROFILE;
}
+static void annotate_encoded_perf_profile(wireless_android_play_playlog::AndroidPerfProfile *profile)
+{
+ //
+ // Load average as reported by the kernel
+ //
+ std::string load;
+ double fload = 0.0;
+ if (android::base::ReadFileToString("/proc/loadavg", &load) &&
+ sscanf(load.c_str(), "%lf", &fload) == 1) {
+ int iload = static_cast<int>(fload * 100.0);
+ profile->set_sys_load_average(iload);
+ } else {
+ W_ALOGE("Failed to read or scan /proc/loadavg (%s)", strerror(errno));
+ }
+
+ //
+ // Examine the contents of wake_unlock to determine whether the
+ // device display is on or off. NB: is this really the only way to
+ // determine this info?
+ //
+ std::string disp;
+ if (android::base::ReadFileToString("/sys/power/wake_unlock", &disp)) {
+ bool ison = (strstr(disp.c_str(), "PowerManagerService.Display") == 0);
+ profile->set_display_on(ison);
+ } else {
+ W_ALOGE("Failed to read /sys/power/wake_unlock (%s)", strerror(errno));
+ }
+}
+
inline char* string_as_array(std::string* str) {
return str->empty() ? NULL : &*str->begin();
}
@@ -499,6 +531,13 @@ PROFILE_RESULT encode_to_proto(const std::string &data_file_path,
return ERR_PERF_ENCODE_FAILED;
}
+ // All of the info in 'encodedProfile' is derived from the perf.data file;
+ // here we tack display status and system load.
+ wireless_android_play_playlog::AndroidPerfProfile &prof =
+ const_cast<wireless_android_play_playlog::AndroidPerfProfile&>
+ (encodedProfile);
+ annotate_encoded_perf_profile(&prof);
+
//
// Serialize protobuf to array
//
@@ -636,6 +675,9 @@ static void cleanup_destination_dir(const ConfigReader &config)
}
}
closedir(dir);
+ } else {
+ W_ALOGW("unable to open destination dir %s for cleanup",
+ dest_dir.c_str());
}
}
@@ -680,7 +722,8 @@ static bool post_process(const ConfigReader &config, int current_seq)
fclose(fp);
}
- if (produced.size() >= MAX_UNPROCESSED_FILE) {
+ unsigned maxLive = config.getUnsignedValue("max_unprocessed_profiles");
+ if (produced.size() >= maxLive) {
return false;
}
@@ -774,12 +817,11 @@ static PROFILE_RESULT collect_profile(const ConfigReader &config, int seq)
}
//
-// SIGHUP handler. Sets a flag to indicate that we should reread the
-// config file
+// SIGHUP handler. Sending SIGHUP to the daemon can be used to break it
+// out of a sleep() call so as to trigger a new collection (debugging)
//
static void sig_hup(int /* signum */)
{
- please_reread_config_file = 1;
}
//
@@ -828,7 +870,7 @@ static void set_seed(ConfigReader &config)
//
static void init(ConfigReader &config)
{
- config.readFile();
+ config.readFile(true);
set_seed(config);
cleanup_destination_dir(config);
@@ -880,11 +922,9 @@ int perfprofd_main(int argc, char** argv)
config.getUnsignedValue("collection_interval"));
perfprofd_sleep(sleep_before_collect);
- // Reread config file if someone sent a SIGHUP
- if (please_reread_config_file) {
- config.readFile();
- please_reread_config_file = 0;
- }
+ // Reread config file -- the uploader may have rewritten it as a result
+ // of a gservices change
+ config.readFile(false);
// Check for profiling enabled...
CKPROFILE_RESULT ckresult = check_profiling_enabled(config);
diff --git a/perfprofd/perfprofdcore.h b/perfprofd/perfprofdcore.h
index f3b1717f..53695e2c 100644
--- a/perfprofd/perfprofdcore.h
+++ b/perfprofd/perfprofdcore.h
@@ -28,9 +28,6 @@
// by perfprofd within the destination directory; consumed by GmsCore.
#define PRODUCED_FILENAME "perfprofd_produced.txt"
-// Maximum number of encoded perf.data files stored in destination dir
-#define MAX_UNPROCESSED_FILE 10
-
// Main routine for perfprofd daemon
extern int perfprofd_main(int argc, char **argv);
diff --git a/perfprofd/tests/perfprofd_test.cc b/perfprofd/tests/perfprofd_test.cc
index 0dd0f737..d13e21e3 100644
--- a/perfprofd/tests/perfprofd_test.cc
+++ b/perfprofd/tests/perfprofd_test.cc
@@ -304,7 +304,7 @@ TEST_F(PerfProfdTest, MissingGMS)
//
PerfProfdRunner runner;
runner.addToConfig("only_debug_build=0");
- runner.addToConfig("trace_config_read=1");
+ runner.addToConfig("trace_config_read=0");
runner.addToConfig("config_directory=/does/not/exist");
runner.addToConfig("main_loop_iterations=1");
runner.addToConfig("use_fixed_seed=1");
@@ -563,6 +563,7 @@ TEST_F(PerfProfdTest, BasicRunWithLivePerf)
runner.addToConfig(cfparam);
runner.addToConfig("main_loop_iterations=1");
runner.addToConfig("use_fixed_seed=12345678");
+ runner.addToConfig("max_unprocessed_profiles=100");
runner.addToConfig("collection_interval=9999");
runner.addToConfig("sample_duration=2");
diff --git a/tests/workloads/capture.sh b/tests/workloads/capture.sh
index 721fe8c8..3b2f446e 100755
--- a/tests/workloads/capture.sh
+++ b/tests/workloads/capture.sh
@@ -5,12 +5,24 @@
# do a throw-away adb in case the server is out-of-date
adb devices -l 2>&1 >/dev/null
-devInfo=$(adb devices -l | grep -v ^List | head -1)
-set -- $devInfo
-echo devInfo=$devInfo
+while [ $# -gt 0 ]
+do
+ case "$1" in
+ (-d) DEVICE=$2; shift;;
+ (*)
+ echo Unknown option $1
+ exit 1;;
+ esac
+ shift
+done
-DEVICE=$(echo $4 | sed 's/product://')
+if [ "$DEVICE" = "" ]; then
+ devInfo=$(adb devices -l | grep -v ^List | head -1)
+ set -- $devInfo
+ echo devInfo=$devInfo
+ DEVICE=$(echo $4 | sed 's/product://')
+fi
function convert {
in=$1
@@ -26,7 +38,7 @@ function convert {
case $DEVICE in
-(shamu|hammerhead)
+(shamu|hammerhead|bullhead)
# no scaling necessary
xmax=0
ymax=0;;
diff --git a/tests/workloads/defs.sh b/tests/workloads/defs.sh
index 838d04f4..a2b71387 100755
--- a/tests/workloads/defs.sh
+++ b/tests/workloads/defs.sh
@@ -11,8 +11,7 @@ generateActivities=0
# default activities. Can dynamically generate with -g.
gmailActivity='com.google.android.gm/com.google.android.gm.ConversationListActivityGmail'
hangoutsActivity='com.google.android.talk/com.google.android.talk.SigningInActivity'
-chromeActivity='com.android.chrome/com.google.android.apps.chrome.ChromeTabbedActivity'
-chromeLActivity='com.android.chrome/com.google.android.apps.chrome.document.DocumentActivity'
+chromeActivity='com.android.chrome/_not_used'
youtubeActivity='com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity'
cameraActivity='com.google.android.GoogleCamera/com.android.camera.CameraActivity'
playActivity='com.android.vending/com.google.android.finsky.activities.MainActivity'
@@ -209,37 +208,41 @@ function getEndTime {
}
function resetJankyFrames {
- ${ADB}dumpsys gfxinfo $1 reset 2>&1 >/dev/null
+ _gfxapp=$1
+ _gfxapp=${app:="com.android.systemui"}
+ ${ADB}dumpsys gfxinfo $_gfxapp reset 2>&1 >/dev/null
}
function getJankyFrames {
- if [ -z "$ADB" ]; then
- # Note: no awk or sed on devices so have to do this
- # purely with bash
- total=0
- janky=0
- /system/bin/dumpsys gfxinfo | grep " frames" | while read line
- do
- if echo $line | grep -q "Total frames"; then
- set -- $line
- ((total=total+$4))
- elif echo $line | grep -q "Janky frames"; then
- set -- $line
- ((janky=janky+$3))
- fi
- # Note: no tail, awk, or sed on 5.x so get final
- # sum via most recently written file
- echo $total $janky > ./janky.$$
- done
- cat ./janky.$$
- rm -f ./janky.$$
- else
- ${ADB}dumpsys gfxinfo $1 | sed -e 's/ //' | awk '
- BEGIN { total=0; janky=0; }
- /Total frames/ { total+=$4; }
- /Janky frames/ { janky+=$3; }
- END { printf "%d %d\n", total, janky; }'
- fi
+ _gfxapp=$1
+ _gfxapp=${_gfxapp:="com.android.systemui"}
+
+ # Note: no awk or sed on devices so have to do this
+ # purely with bash
+ total=0
+ janky=0
+ latency=0
+ ${ADB}dumpsys gfxinfo $_gfxapp | tr "\r" " " | egrep "9[059]th| frames" | while read line
+ do
+ if echo $line | grep -q "Total frames"; then
+ set -- $line
+ total=$4
+ elif echo $line | grep -q "Janky frames"; then
+ set -- $line
+ janky=$3
+ elif echo $line | grep -q "90th"; then
+ set -- $(echo $line | tr m " ")
+ l90=$3
+ elif echo $line | grep -q "95th"; then
+ set -- $(echo $line | tr m " ")
+ l95=$3
+ elif echo $line | grep -q "99th"; then
+ set -- $(echo $line | tr m " ")
+ l99=$3
+ echo $total $janky $l90 $l95 $l99
+ break
+ fi
+ done
}
function checkForDirectReclaim {
@@ -332,9 +335,15 @@ function startActivity {
doKeyevent HOME
echo 0
return 0
- elif [ "$1" = chromeL ]; then
- vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
- set -- $($AM_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
+ elif [ "$1" = chrome ]; then
+ if [ "$DEVICE" = volantis ]; then
+ vout $AM_START_NOWAIT -p "$(getPackageName $1)" http://www.theverge.com
+ $AM_START_NOWAIT -p "$(getPackageName $1)" http://www.theverge.com > /dev/null
+ set -- 0 0
+ else
+ vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
+ set -- $($AM_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
+ fi
else
vout $AM_START "$(getActivityName $1)"
set -- $($AM_START "$(getActivityName $1)" | grep ThisTime)
@@ -343,10 +352,9 @@ function startActivity {
}
function forceStartActivity {
- if [ "$1" = chromeL ]; then
- # force start doesn't work for chrome (hangs on startup)
- startActivity $*
- return 0
+ if [ "$1" = chrome ]; then
+ vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
+ set -- $($AM_FORCE_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
else
vout $AM_FORCE_START "$(getActivityName $1)"
set -- $($AM_FORCE_START "$(getActivityName $1)" | grep ThisTime)
diff --git a/tests/workloads/recentfling.sh b/tests/workloads/recentfling.sh
index 68fdb2ff..092c8d92 100755
--- a/tests/workloads/recentfling.sh
+++ b/tests/workloads/recentfling.sh
@@ -44,6 +44,12 @@ case $DEVICE in
upCount=6
UP="70 400 70 100 $flingtime"
DOWN="70 100 70 400 $flingtime";;
+(bullhead)
+ flingtime=200
+ downCount=5
+ upCount=5
+ UP="500 1200 500 550 $flingtime"
+ DOWN="500 550 500 1200 $flingtime";;
(volantis)
flingtime=400
downCount=5
@@ -66,20 +72,6 @@ if [ $startapps -gt 0 ]; then
done
fi
-cur=1
-
-set -- $(getJankyFrames)
-totalFrames=$1
-jankyFrames=$2
-frameSum=0
-jankSum=0
-
-if [ ${totalFrames:=0} -eq 0 ]; then
-#echo Error: could not read frame info with \"dumpsys graphicsstats\"
- echo Error: could not read frame info with \"dumpsys gfxinfo\"
- exit 1
-fi
-
function swipe {
count=0
while [ $count -lt $2 ]
@@ -89,14 +81,25 @@ function swipe {
done
}
+cur=1
+frameSum=0
+jankSum=0
+latency90Sum=0
+latency95Sum=0
+latency99Sum=0
+
echo Fling recents...
-doKeyevent APP_SWITCH
+doKeyevent HOME
+sleep 0.5
+resetJankyFrames
while [ $cur -le $iterations ]
do
if [ $capturesystrace -gt 0 ]; then
${ADB}atrace --async_start -z -c -b 16000 freq gfx view idle sched
fi
+ doKeyevent APP_SWITCH
+ sleep 0.5
swipe "$DOWN" $downCount
sleep 1
swipe "$UP" $upCount
@@ -108,25 +111,40 @@ do
if [ $capturesystrace -gt 0 ]; then
${ADB}atrace --async_dump -z -c -b 16000 freq gfx view idle sched > trace.${cur}.out
fi
+ doKeyevent HOME
+ sleep 0.5
set -- $(getJankyFrames)
- newTotalFrames=$1
- newJankyFrames=$2
- ((totalDiff=newTotalFrames-totalFrames))
+ totalDiff=$1
+ jankyDiff=$2
+ latency90=$3
+ latency95=$4
+ latency99=$5
+ if [ ${totalDiff:=0} -eq 0 ]; then
+ echo Error: could not read frame info with \"dumpsys gfxinfo\"
+ exit 1
+ fi
+
((frameSum=frameSum+totalDiff))
- ((jankyDiff=newJankyFrames-jankyFrames))
((jankSum=jankSum+jankyDiff))
+ ((latency90Sum=latency90Sum+latency90))
+ ((latency95Sum=latency95Sum+latency95))
+ ((latency99Sum=latency99Sum+latency99))
if [ "$totalDiff" -eq 0 ]; then
echo Error: no frames detected. Is the display off?
exit 1
fi
((jankPct=jankyDiff*100/totalDiff))
- totalFrames=$newTotalFrames
- jankyFrames=$newJankyFrames
+ resetJankyFrames
- echo Frames: $totalDiff Janks: $jankyDiff \(${jankPct}%\)
+ echo Frames: $totalDiff latency: $latency90/$latency95/$latency99 Janks: $jankyDiff\(${jankPct}%\)
((cur=cur+1))
done
doKeyevent HOME
((aveJankPct=jankSum*100/frameSum))
-echo AVE: Frames: $frameSum Janks: $jankSum \(${aveJankPct}%\)
+((aveJanks=jankSum/iterations))
+((aveFrames=frameSum/iterations))
+((aveLatency90=latency90Sum/iterations))
+((aveLatency95=latency95Sum/iterations))
+((aveLatency99=latency99Sum/iterations))
+echo AVE: Frames: $aveFrames latency: $aveLatency90/$aveLatency95/$aveLatency99 Janks: $aveJanks\(${aveJankPct}%\)
diff --git a/tests/workloads/systemapps.sh b/tests/workloads/systemapps.sh
index 184c4ee4..a263e7d2 100755
--- a/tests/workloads/systemapps.sh
+++ b/tests/workloads/systemapps.sh
@@ -26,6 +26,7 @@ iterations=1
tracecategories="gfx view am input memreclaim"
totaltimetest=0
forcecoldstart=0
+waitTime=3.0
appList="gmail hangouts chrome youtube play home"
@@ -36,6 +37,7 @@ function processLocalOption {
(-F) forcecoldstart=1;;
(-L) appList=$2; shift; ret=1;;
(-T) totaltimetest=1;;
+ (-W) waitTime=$2; shift; ret=1;;
(*)
echo "$0: unrecognized option: $1"
echo; echo "Usage: $0 [options]"
@@ -44,6 +46,7 @@ function processLocalOption {
echo "-L applist : list of applications"
echo " default: $appList"
echo "-T : total time to start all apps"
+ echo "-W : time to wait between apps"
echo "-g : generate activity strings"
echo "-i iterations"
echo "-n : keep trace files"
@@ -74,6 +77,9 @@ function computeStats {
reclaim=$4
frames=$5
janks=$6
+ l90=$7
+ l95=$8
+ l99=$9
curMax=$(eval "echo \$${label}max")
curMax=${curMax:=0}
curMin=$(eval "echo \$${label}min")
@@ -88,6 +94,12 @@ function computeStats {
curFrames=${curFrames:=0}
curJanks=$(eval "echo \$${label}janks")
curJanks=${curJanks:=0}
+ cur90=$(eval "echo \$${label}90")
+ cur90=${cur90:=0}
+ cur95=$(eval "echo \$${label}95")
+ cur95=${cur95:=0}
+ cur99=$(eval "echo \$${label}99")
+ cur99=${cur99:=0}
if [ $curMax -lt $t ]; then
eval "${label}max=$t"
fi
@@ -105,12 +117,19 @@ function computeStats {
eval "${label}frames=$curFrames"
((curJanks=curJanks+${janks:=0}))
eval "${label}janks=$curJanks"
+ ((cur90=cur90+${l90:=0}))
+ eval "${label}90=$cur90"
+ ((cur95=cur95+${l95:=0}))
+ eval "${label}95=$cur95"
+ ((cur99=cur99+${l99:=0}))
+ eval "${label}99=$cur99"
}
function getStats {
label=$1
echo $(eval "echo \$${label}max") $(eval "echo \$${label}min") $(eval "echo \$${label}sum") \
$(eval "echo \$${label}restart") $(eval "echo \$${label}reclaim") \
- $(eval "echo \$${label}frames") $(eval "echo \$${label}janks")
+ $(eval "echo \$${label}frames") $(eval "echo \$${label}janks") \
+ $(eval "echo \$${label}90") $(eval "echo \$${label}95") $(eval "echo \$${label}99")
}
cur=1
@@ -126,7 +145,7 @@ do
fi
if [ $iterations -gt 1 -o $cur -eq 1 ]; then
if [ $totaltimetest -eq 0 ]; then
- printf "%-6s %7s(ms) %6s(ms) %s %s %s %s\n" App Time AmTime Restart DirReclaim JankyFrames
+ printf "%-6s %7s(ms) %6s(ms) %s %s %s %s\n" App Time AmTime Restart DirReclaim Jank Latency
fi
fi
@@ -136,53 +155,80 @@ do
vout Starting $app...
((appnum=appnum+1))
loopTimestamp=$(date +"%s %N")
- if [ $totaltimetest -gt 0 ]; then
- # no instramentation, just cycle through the apps
+ resetJankyFrames
+ resetJankyFrames $(getPackageName $app)
+ if [ $totaltimetest -eq 0 ]; then
+ tmpTraceOut="$tmpTraceOutBase-$app.out"
+ >$tmpTraceOut
+ startInstramentation
+ else
if [ $appnum -eq 0 ]; then
- printf "%-8s %5s(ms) %3s(ms)\n" App Start Iter
+ printf "%-8s %5s(ms) %3s(ms) %s %s\n" App Start Iter Jank Latency
fi
- if [ $forcecoldstart -eq 0 ]; then
- t=$(startActivity $app)
- else
- t=$(forceStartActivity $app)
- fi
- loopEndTimestamp=$(date +"%s %N")
- diffTime=$(computeTimeDiff $loopTimestamp $loopEndTimestamp)
- # Note: "%d" doesn't work right if run on device
- printf "%-10s %5.0f %5.0f\n" $app $t $diffTime
- ((totaltime=totaltime+t))
- continue
fi
- tmpTraceOut="$tmpTraceOutBase-$app.out"
- >$tmpTraceOut
- startInstramentation
- resetJankyFrames $(getPackageName $app)
- t=$(startActivity $app)
+ if [ $forcecoldstart -eq 0 ]; then
+ t=$(startActivity $app)
+ else
+ t=$(forceStartActivity $app)
+ fi
+
# let app finish drawing before checking janks
- sleep 3
+ sleep $waitTime
set -- $(getJankyFrames $(getPackageName $app))
frames=$1
janks=$2
- ((jankPct=100*janks/frames))
- stopAndDumpInstramentation $tmpTraceOut
- actName=$(getActivityName $app)
- stime=$(getStartTime $actName $tmpTraceOut)
- relaunch=$?
- etime=$(getEndTime $actName $tmpTraceOut)
- ((tdiff=$etime-$stime))
- if [ $etime -eq 0 -o $stime -eq 0 ]; then
- handleError $app : could not compute start time stime=$stime etime=$etime
- # use AmTime so statistics make sense
- tdiff=$t
+ l90=$3
+ l95=$4
+ l99=$5
+ set -- $(getJankyFrames)
+ systemFrames=$1
+ systemJanks=$2
+ s90=$3
+ s95=$4
+ s99=$5
+ ((frames=frames+systemFrames))
+ ((janks=janks+systemJanks))
+ ((l90=l90+s90))
+ ((l95=l95+s95))
+ ((l99=l99+s99))
+
+ loopEndTimestamp=$(date +"%s %N")
+ diffTime=$(computeTimeDiff $loopTimestamp $loopEndTimestamp)
+
+ if [ $frames -eq 0 ]; then
+ janks=0
+ jankPct=0
+ else
+ ((jankPct=100*janks/frames))
fi
- checkForDirectReclaim $actName $tmpTraceOut
- directReclaim=$?
+ if [ $totaltimetest -gt 0 ]; then
+ # Note: using %f since %d doesn't work correctly
+ # when running on lollipop
+ printf "%-10s %5.0f %5.0f %4.0f(%2.0f%%) %2.0f/%2.0f/%2.0f\n" $app $t $diffTime $janks $jankPct $l90 $l95 $l99
+ ((totaltime=totaltime+t))
+ continue
+ else
+ stopAndDumpInstramentation $tmpTraceOut
+ actName=$(getActivityName $app)
+ pkgName=$(getPackageName $app)
+ stime=$(getStartTime $actName $tmpTraceOut)
+ relaunch=$?
+ etime=$(getEndTime $pkgName $tmpTraceOut)
+ ((tdiff=$etime-$stime))
+ if [ $etime -eq 0 -o $stime -eq 0 ]; then
+ handleError $app : could not compute start time stime=$stime etime=$etime
+ # use AmTime so statistics make sense
+ tdiff=$t
+ fi
+ checkForDirectReclaim $actName $tmpTraceOut
+ directReclaim=$?
- printf "%-12s %5d %5d %5d %5d %5d(%d%%)\n" "$app" "$tdiff" "$t" "$relaunch" "$directReclaim" "$janks" "$jankPct"
- computeStats "$app" "$tdiff" "$relaunch" "$directReclaim" "$frames" "$janks"
+ printf "%-12s %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" "$app" "$tdiff" "$t" "$relaunch" "$directReclaim" "$janks" "$jankPct" $l90 $l95 $l99
+ computeStats "$app" "$tdiff" "$relaunch" "$directReclaim" "$frames" "$janks" $l90 $l95 $l99
- if [ $savetmpfiles -eq 0 ]; then
- rm -f $tmpTraceOut
+ if [ $savetmpfiles -eq 0 ]; then
+ rm -f $tmpTraceOut
+ fi
fi
done
((cur=cur+1))
@@ -198,7 +244,7 @@ if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then
echo =========================================
printf "Stats after $iterations iterations:\n"
echo =========================================
- printf "%-6s %7s(ms) %6s(ms) %6s(ms) %s %s %s %s\n" App Max Ave Min Restart DirReclaim JankyFrames
+ printf "%-6s %7s(ms) %6s(ms) %6s(ms) %s %s %s %s\n" App Max Ave Min Restart DirReclaim Jank Latency
for app in $appList
do
set -- $(getStats $app)
@@ -206,7 +252,13 @@ if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then
((ave=sum/iterations))
frames=$6
janks=$7
+ l90=$8
+ l95=$9
+ l99=${10}
+ ((ave90=l90/iterations))
+ ((ave95=l95/iterations))
+ ((ave99=l99/iterations))
((jankPct=100*janks/frames))
- printf "%-12s %5d %5d %5d %5d %5d %5d(%d%%)\n" $app $1 $ave $2 $4 $5 $janks $jankPct
+ printf "%-12s %5d %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" $app $1 $ave $2 $4 $5 $janks $jankPct $ave90 $ave95 $ave99
done
fi
diff --git a/verity/Android.mk b/verity/Android.mk
index 46396ca2..75face6f 100644
--- a/verity/Android.mk
+++ b/verity/Android.mk
@@ -1,5 +1,6 @@
LOCAL_PATH:= $(call my-dir)
+ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
LOCAL_MODULE := verify_boot_signature
LOCAL_SRC_FILES := verify_boot_signature.c
@@ -8,6 +9,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := libcrypto-host
LOCAL_C_INCLUDES += external/openssl/include system/extras/ext4_utils system/core/mkbootimg
include $(BUILD_HOST_EXECUTABLE)
+endif
include $(CLEAR_VARS)
LOCAL_MODULE := generate_verity_key