diff options
40 files changed, 992 insertions, 1743 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index 05b0284a1..2b6df7060 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -133,7 +133,7 @@ LOCAL_SANITIZE := $(adb_target_sanitize) # Even though we're building a static library (and thus there's no link step for # this to take effect), this adds the includes to our path. -LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase +LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libqemu_pipe libbase LOCAL_WHOLE_STATIC_LIBRARIES := libadbd_usb @@ -363,6 +363,7 @@ LOCAL_STATIC_LIBRARIES := \ libasyncio \ libavb_user \ libbase \ + libqemu_pipe \ libbootloader_message \ libfs_mgr \ libfec \ diff --git a/adb/framebuffer_service.cpp b/adb/framebuffer_service.cpp index 7baad8b72..6c3a2252f 100644 --- a/adb/framebuffer_service.cpp +++ b/adb/framebuffer_service.cpp @@ -37,10 +37,11 @@ */ /* This version number defines the format of the fbinfo struct. It must match versioning in ddms where this data is consumed. */ -#define DDMS_RAWIMAGE_VERSION 1 +#define DDMS_RAWIMAGE_VERSION 2 struct fbinfo { unsigned int version; unsigned int bpp; + unsigned int colorSpace; unsigned int size; unsigned int width; unsigned int height; @@ -60,7 +61,7 @@ void framebuffer_service(int fd, void *cookie) unsigned int i, bsize; char buf[640]; int fd_screencap; - int w, h, f; + int w, h, f, c; int fds[2]; pid_t pid; @@ -82,12 +83,14 @@ void framebuffer_service(int fd, void *cookie) adb_close(fds[1]); fd_screencap = fds[0]; - /* read w, h & format */ + /* read w, h, format & color space */ if(!ReadFdExactly(fd_screencap, &w, 4)) goto done; if(!ReadFdExactly(fd_screencap, &h, 4)) goto done; if(!ReadFdExactly(fd_screencap, &f, 4)) goto done; + if(!ReadFdExactly(fd_screencap, &c, 4)) goto done; fbinfo.version = DDMS_RAWIMAGE_VERSION; + fbinfo.colorSpace = c; /* see hardware/hardware.h */ switch (f) { case 1: /* RGBA_8888 */ diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp index 6cedd92b5..9cd378cad 100644 --- a/adb/transport_local.cpp +++ b/adb/transport_local.cpp @@ -288,7 +288,7 @@ static void server_socket_thread(int port) { #define open adb_open #define read adb_read #define write adb_write -#include <system/qemu_pipe.h> +#include <qemu_pipe.h> #undef open #undef read #undef write diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 074f83840..4b94f9c97 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -738,6 +738,12 @@ static bool needs_block_encryption(const struct fstab_rec* rec) return false; } +static bool should_use_metadata_encryption(const struct fstab_rec* rec) { + if (!(rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE))) return false; + if (!(rec->fs_mgr_flags & MF_KEYDIRECTORY)) return false; + return true; +} + // Check to see if a mountable volume has encryption requirements static int handle_encryptable(const struct fstab_rec* rec) { @@ -750,8 +756,14 @@ static int handle_encryptable(const struct fstab_rec* rec) << " - allow continue unencrypted"; return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; } + } else if (should_use_metadata_encryption(rec)) { + if (umount(rec->mount_point) == 0) { + return FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION; + } else { + PERROR << "Could not umount " << rec->mount_point << " - fail since can't encrypt"; + return FS_MGR_MNTALL_FAIL; + } } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) { - // Deal with file level encryption LINFO << rec->mount_point << " is file encrypted"; return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED; } else if (fs_mgr_is_encryptable(rec)) { @@ -873,7 +885,6 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) continue; } - /* mount(2) returned an error, handle the encryptable/formattable case */ bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); bool crypt_footer = false; if (mret && mount_errno != EBUSY && mount_errno != EACCES && @@ -913,6 +924,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) continue; } } + + /* mount(2) returned an error, handle the encryptable/formattable case */ if (mret && mount_errno != EBUSY && mount_errno != EACCES && fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { if (wiped) { @@ -938,6 +951,9 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) } } encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; + } else if (mret && mount_errno != EBUSY && mount_errno != EACCES && + should_use_metadata_encryption(&fstab->recs[attempted_idx])) { + encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; } else { // fs_options might be null so we cannot use PERROR << directly. // Use StringPrintf to output "(null)" instead. @@ -1220,48 +1236,46 @@ int fs_mgr_swapon_all(struct fstab *fstab) return ret; } -/* - * key_loc must be at least PROPERTY_VALUE_MAX bytes long - * - * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long - */ -int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size) -{ - int i = 0; +struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab) { + int i; if (!fstab) { - return -1; - } - /* Initialize return values to null strings */ - if (key_loc) { - *key_loc = '\0'; - } - if (real_blk_device) { - *real_blk_device = '\0'; + return NULL; } /* Look for the encryptable partition to find the data */ for (i = 0; i < fstab->num_entries; i++) { /* Don't deal with vold managed enryptable partitions here */ - if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) { - continue; - } - if (!(fstab->recs[i].fs_mgr_flags - & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) { - continue; + if (!(fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) && + (fstab->recs[i].fs_mgr_flags & + (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE | MF_FILEENCRYPTION))) { + return &fstab->recs[i]; } + } + return NULL; +} - /* We found a match */ - if (key_loc) { - strlcpy(key_loc, fstab->recs[i].key_loc, size); +/* + * key_loc must be at least PROPERTY_VALUE_MAX bytes long + * + * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long + */ +void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size) { + struct fstab_rec const* rec = fs_mgr_get_crypt_entry(fstab); + if (key_loc) { + if (rec) { + strlcpy(key_loc, rec->key_loc, size); + } else { + *key_loc = '\0'; } - if (real_blk_device) { - strlcpy(real_blk_device, fstab->recs[i].blk_device, size); + } + if (real_blk_device) { + if (rec) { + strlcpy(real_blk_device, rec->blk_device, size); + } else { + *real_blk_device = '\0'; } - break; } - - return 0; } bool fs_mgr_load_verity_state(int* mode) { diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index bce245ce3..92c6ee8c0 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -33,6 +33,7 @@ const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android"); struct fs_mgr_flag_values { char *key_loc; + char* key_dir; char *verity_loc; long long part_length; char *label; @@ -72,34 +73,35 @@ static struct flag_list mount_flags[] = { }; static struct flag_list fs_mgr_flags[] = { - { "wait", MF_WAIT }, - { "check", MF_CHECK }, - { "encryptable=", MF_CRYPT }, - { "forceencrypt=", MF_FORCECRYPT }, - { "fileencryption=", MF_FILEENCRYPTION }, - { "forcefdeorfbe=", MF_FORCEFDEORFBE }, - { "nonremovable", MF_NONREMOVABLE }, - { "voldmanaged=", MF_VOLDMANAGED}, - { "length=", MF_LENGTH }, - { "recoveryonly", MF_RECOVERYONLY }, - { "swapprio=", MF_SWAPPRIO }, - { "zramsize=", MF_ZRAMSIZE }, - { "max_comp_streams=", MF_MAX_COMP_STREAMS }, - { "verifyatboot", MF_VERIFYATBOOT }, - { "verify", MF_VERIFY }, - { "avb", MF_AVB }, - { "noemulatedsd", MF_NOEMULATEDSD }, - { "notrim", MF_NOTRIM }, - { "formattable", MF_FORMATTABLE }, - { "slotselect", MF_SLOTSELECT }, - { "nofail", MF_NOFAIL }, - { "latemount", MF_LATEMOUNT }, - { "reservedsize=", MF_RESERVEDSIZE }, - { "quota", MF_QUOTA }, - { "eraseblk=", MF_ERASEBLKSIZE }, - { "logicalblk=", MF_LOGICALBLKSIZE }, - { "defaults", 0 }, - { 0, 0 }, + {"wait", MF_WAIT}, + {"check", MF_CHECK}, + {"encryptable=", MF_CRYPT}, + {"forceencrypt=", MF_FORCECRYPT}, + {"fileencryption=", MF_FILEENCRYPTION}, + {"forcefdeorfbe=", MF_FORCEFDEORFBE}, + {"keydirectory=", MF_KEYDIRECTORY}, + {"nonremovable", MF_NONREMOVABLE}, + {"voldmanaged=", MF_VOLDMANAGED}, + {"length=", MF_LENGTH}, + {"recoveryonly", MF_RECOVERYONLY}, + {"swapprio=", MF_SWAPPRIO}, + {"zramsize=", MF_ZRAMSIZE}, + {"max_comp_streams=", MF_MAX_COMP_STREAMS}, + {"verifyatboot", MF_VERIFYATBOOT}, + {"verify", MF_VERIFY}, + {"avb", MF_AVB}, + {"noemulatedsd", MF_NOEMULATEDSD}, + {"notrim", MF_NOTRIM}, + {"formattable", MF_FORMATTABLE}, + {"slotselect", MF_SLOTSELECT}, + {"nofail", MF_NOFAIL}, + {"latemount", MF_LATEMOUNT}, + {"reservedsize=", MF_RESERVEDSIZE}, + {"quota", MF_QUOTA}, + {"eraseblk=", MF_ERASEBLKSIZE}, + {"logicalblk=", MF_LOGICALBLKSIZE}, + {"defaults", 0}, + {0, 0}, }; #define EM_AES_256_XTS 1 @@ -268,6 +270,11 @@ static int parse_flags(char *flags, struct flag_list *fl, } else { flag_vals->file_names_mode = EM_AES_256_CTS; } + } else if ((fl[i].flag == MF_KEYDIRECTORY) && flag_vals) { + /* The metadata flag is followed by an = and the + * directory for the keys. Get it and return it. + */ + flag_vals->key_dir = strdup(strchr(p, '=') + 1); } else if ((fl[i].flag == MF_LENGTH) && flag_vals) { /* The length flag is followed by an = and the * size of the partition. Get it and return it. @@ -577,6 +584,7 @@ static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, &flag_vals, NULL, 0); fstab->recs[cnt].key_loc = flag_vals.key_loc; + fstab->recs[cnt].key_dir = flag_vals.key_dir; fstab->recs[cnt].verity_loc = flag_vals.verity_loc; fstab->recs[cnt].length = flag_vals.part_length; fstab->recs[cnt].label = flag_vals.label; @@ -736,6 +744,7 @@ void fs_mgr_free_fstab(struct fstab *fstab) free(fstab->recs[i].fs_type); free(fstab->recs[i].fs_options); free(fstab->recs[i].key_loc); + free(fstab->recs[i].key_dir); free(fstab->recs[i].label); } diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index c3c87fa81..724156d70 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -109,6 +109,7 @@ #define MF_ERASEBLKSIZE 0x800000 #define MF_LOGICALBLKSIZE 0X1000000 #define MF_AVB 0X2000000 +#define MF_KEYDIRECTORY 0X4000000 #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index 5c26c2ebe..653d8fa01 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -51,6 +51,8 @@ enum mount_mode { typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab, const char *mount_point, int mode, int status); +#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7 +#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6 #define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5 #define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4 #define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 3 @@ -69,8 +71,8 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, int fs_mgr_do_mount_one(struct fstab_rec *rec); int fs_mgr_do_tmpfs_mount(const char *n_name); int fs_mgr_unmount_all(struct fstab *fstab); -int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, - char *real_blk_device, int size); +struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab); +void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size); bool fs_mgr_load_verity_state(int* mode); bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); int fs_mgr_swapon_all(struct fstab *fstab); diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h index bc2942d0c..94aacfdb3 100644 --- a/fs_mgr/include_fstab/fstab/fstab.h +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -43,6 +43,7 @@ struct fstab_rec { char* fs_options; int fs_mgr_flags; char* key_loc; + char* key_dir; char* verity_loc; long long length; char* label; diff --git a/gatekeeperd/IGateKeeperService.cpp b/gatekeeperd/IGateKeeperService.cpp index 95fbfd10b..1c339f4c8 100644 --- a/gatekeeperd/IGateKeeperService.cpp +++ b/gatekeeperd/IGateKeeperService.cpp @@ -158,6 +158,12 @@ status_t BnGateKeeperService::onTransact( reply->writeNoException(); return NO_ERROR; } + case REPORT_DEVICE_SETUP_COMPLETE: { + CHECK_INTERFACE(IGateKeeperService, data, reply); + reportDeviceSetupComplete(); + reply->writeNoException(); + return NO_ERROR; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/gatekeeperd/IGateKeeperService.h b/gatekeeperd/IGateKeeperService.h index f070486cd..2816efc6a 100644 --- a/gatekeeperd/IGateKeeperService.h +++ b/gatekeeperd/IGateKeeperService.h @@ -33,6 +33,7 @@ public: VERIFY_CHALLENGE = IBinder::FIRST_CALL_TRANSACTION + 2, GET_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 3, CLEAR_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 4, + REPORT_DEVICE_SETUP_COMPLETE = IBinder::FIRST_CALL_TRANSACTION + 5, }; enum { @@ -95,6 +96,12 @@ public: * Clears the secure user ID associated with the user. */ virtual void clearSecureUserId(uint32_t uid) = 0; + + /** + * Notifies gatekeeper that device setup has been completed and any potentially still existing + * state from before a factory reset can be cleaned up (if it has not been already). + */ + virtual void reportDeviceSetupComplete() = 0; }; // ---------------------------------------------------------------------------- diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp index 73dab9b9e..d581736f3 100644 --- a/gatekeeperd/gatekeeperd.cpp +++ b/gatekeeperd/gatekeeperd.cpp @@ -57,19 +57,13 @@ static const String16 DUMP_PERMISSION("android.permission.DUMP"); class GateKeeperProxy : public BnGateKeeperService { public: GateKeeperProxy() { + clear_state_if_needed_done = false; hw_device = IGatekeeper::getService(); if (hw_device == nullptr) { ALOGW("falling back to software GateKeeper"); soft_device.reset(new SoftGateKeeperDevice()); } - - if (mark_cold_boot()) { - ALOGI("cold boot: clearing state"); - if (hw_device != nullptr) { - hw_device->deleteAllUsers([](const GatekeeperResponse &){}); - } - } } virtual ~GateKeeperProxy() { @@ -87,6 +81,21 @@ public: close(fd); } + void clear_state_if_needed() { + if (clear_state_if_needed_done) { + return; + } + + if (mark_cold_boot()) { + ALOGI("cold boot: clearing state"); + if (hw_device != nullptr) { + hw_device->deleteAllUsers([](const GatekeeperResponse &){}); + } + } + + clear_state_if_needed_done = true; + } + bool mark_cold_boot() { const char *filename = ".coldboot"; if (access(filename, F_OK) == -1) { @@ -141,6 +150,10 @@ public: return PERMISSION_DENIED; } + // Make sure to clear any state from before factory reset as soon as a credential is + // enrolled (which may happen during device setup). + clear_state_if_needed(); + // need a desired password to enroll if (desired_password_length == 0) return -EINVAL; @@ -355,6 +368,18 @@ public: } } + virtual void reportDeviceSetupComplete() { + IPCThreadState* ipc = IPCThreadState::self(); + const int calling_pid = ipc->getCallingPid(); + const int calling_uid = ipc->getCallingUid(); + if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) { + ALOGE("%s: permission denied for [%d:%d]", __func__, calling_pid, calling_uid); + return; + } + + clear_state_if_needed(); + } + virtual status_t dump(int fd, const Vector<String16> &) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); @@ -377,6 +402,8 @@ public: private: sp<IGatekeeper> hw_device; std::unique_ptr<SoftGateKeeperDevice> soft_device; + + bool clear_state_if_needed_done; }; }// namespace android diff --git a/healthd/Android.mk b/healthd/Android.mk index 8b5996442..6b14289e8 100644 --- a/healthd/Android.mk +++ b/healthd/Android.mk @@ -33,6 +33,30 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) +LOCAL_MODULE := libhealthd_draw + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +LOCAL_STATIC_LIBRARIES := \ + libminui \ + libbase +LOCAL_SRC_FILES := healthd_draw.cpp + +ifneq ($(TARGET_HEALTHD_DRAW_SPLIT_SCREEN),) +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_SCREEN=$(TARGET_HEALTHD_DRAW_SPLIT_SCREEN) +else +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_SCREEN=0 +endif + +ifneq ($(TARGET_HEALTHD_DRAW_SPLIT_OFFSET),) +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_OFFSET=$(TARGET_HEALTHD_DRAW_SPLIT_OFFSET) +else +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_OFFSET=0 +endif + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + LOCAL_CFLAGS := -Werror ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true) LOCAL_CFLAGS += -DCHARGER_DISABLE_INIT_BLANK @@ -58,6 +82,7 @@ LOCAL_STATIC_LIBRARIES := \ libutils \ libbase \ libcutils \ + libhealthd_draw \ liblog \ libm \ libc \ @@ -101,6 +126,7 @@ endif LOCAL_STATIC_LIBRARIES := \ libhealthd_charger \ + libhealthd_draw \ libbatterymonitor \ libbase \ libutils \ diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp new file mode 100644 index 000000000..ea3d991c0 --- /dev/null +++ b/healthd/healthd_draw.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/stringprintf.h> +#include <batteryservice/BatteryService.h> +#include <cutils/klog.h> + +#include "healthd_draw.h" + +#define LOGE(x...) KLOG_ERROR("charger", x); +#define LOGV(x...) KLOG_DEBUG("charger", x); + +HealthdDraw::HealthdDraw(animation* anim) + : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), + kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { + gr_init(); + gr_font_size(gr_sys_font(), &char_width_, &char_height_); + + screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1); + screen_height_ = gr_fb_height(); + + int res; + if (!anim->text_clock.font_file.empty() && + (res = gr_init_font(anim->text_clock.font_file.c_str(), + &anim->text_clock.font)) < 0) { + LOGE("Could not load time font (%d)\n", res); + } + if (!anim->text_percent.font_file.empty() && + (res = gr_init_font(anim->text_percent.font_file.c_str(), + &anim->text_percent.font)) < 0) { + LOGE("Could not load percent font (%d)\n", res); + } +} + +HealthdDraw::~HealthdDraw() {} + +void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { + clear_screen(); + + /* try to display *something* */ + if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) + draw_unknown(surf_unknown); + else + draw_battery(batt_anim); + gr_flip(); +} + +void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); } + +void HealthdDraw::clear_screen(void) { + gr_color(0, 0, 0, 255); + gr_clear(); +} + +int HealthdDraw::draw_surface_centered(GRSurface* surface) { + int w = gr_get_width(surface); + int h = gr_get_height(surface); + int x = (screen_width_ - w) / 2 + kSplitOffset; + int y = (screen_height_ - h) / 2; + + LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); + gr_blit(surface, 0, 0, w, h, x, y); + if (kSplitScreen) { + x += screen_width_ - 2 * kSplitOffset; + LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); + gr_blit(surface, 0, 0, w, h, x, y); + } + + return y + h; +} + +int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) { + int str_len_px = gr_measure(font, str); + + if (x < 0) x = (screen_width_ - str_len_px) / 2; + if (y < 0) y = (screen_height_ - char_height_) / 2; + gr_text(font, x + kSplitOffset, y, str, false /* bold */); + if (kSplitScreen) + gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */); + + return y + char_height_; +} + +void HealthdDraw::determine_xy(const animation::text_field& field, + const int length, int* x, int* y) { + *x = field.pos_x; + + int str_len_px = length * field.font->char_width; + if (field.pos_x == CENTER_VAL) { + *x = (screen_width_ - str_len_px) / 2; + } else if (field.pos_x >= 0) { + *x = field.pos_x; + } else { // position from max edge + *x = screen_width_ + field.pos_x - str_len_px - kSplitOffset; + } + + *y = field.pos_y; + + if (field.pos_y == CENTER_VAL) { + *y = (screen_height_ - field.font->char_height) / 2; + } else if (field.pos_y >= 0) { + *y = field.pos_y; + } else { // position from max edge + *y = screen_height_ + field.pos_y - field.font->char_height; + } +} + +void HealthdDraw::draw_clock(const animation* anim) { + static constexpr char CLOCK_FORMAT[] = "%H:%M"; + static constexpr int CLOCK_LENGTH = 6; + + const animation::text_field& field = anim->text_clock; + + if (field.font == nullptr || field.font->char_width == 0 || + field.font->char_height == 0) + return; + + time_t rawtime; + time(&rawtime); + tm* time_info = localtime(&rawtime); + + char clock_str[CLOCK_LENGTH]; + size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); + if (length != CLOCK_LENGTH - 1) { + LOGE("Could not format time\n"); + return; + } + + int x, y; + determine_xy(field, length, &x, &y); + + LOGV("drawing clock %s %d %d\n", clock_str, x, y); + gr_color(field.color_r, field.color_g, field.color_b, field.color_a); + draw_text(field.font, x, y, clock_str); +} + +void HealthdDraw::draw_percent(const animation* anim) { + 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%%", cur_level); + + int x, y; + determine_xy(field, str.size(), &x, &y); + + LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); + gr_color(field.color_r, field.color_g, field.color_b, field.color_a); + draw_text(field.font, x, y, str.c_str()); +} + +void HealthdDraw::draw_battery(const animation* anim) { + const animation::frame& frame = anim->frames[anim->cur_frame]; + + if (anim->num_frames != 0) { + draw_surface_centered(frame.surface); + LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, + frame.min_level, frame.disp_time); + } + draw_clock(anim); + draw_percent(anim); +} + +void HealthdDraw::draw_unknown(GRSurface* surf_unknown) { + int y; + if (surf_unknown) { + draw_surface_centered(surf_unknown); + } else { + gr_color(0xa4, 0xc6, 0x39, 255); + y = draw_text(gr_sys_font(), -1, -1, "Charging!"); + draw_text(gr_sys_font(), -1, y + 25, "?\?/100"); + } +} diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h new file mode 100644 index 000000000..6a6ba7655 --- /dev/null +++ b/healthd/healthd_draw.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HEALTHD_DRAW_H +#define HEALTHD_DRAW_H + +#include <linux/input.h> +#include <minui/minui.h> + +#include "animation.h" + +using namespace android; + +class HealthdDraw { + public: + // Configures font using given animation. + HealthdDraw(animation* anim); + virtual ~HealthdDraw(); + + // Redraws screen. + void redraw_screen(const animation* batt_anim, GRSurface* surf_unknown); + + // Blanks screen if true, unblanks if false. + virtual void blank_screen(bool blank); + + protected: + virtual void clear_screen(); + + // returns the last y-offset of where the surface ends. + virtual int draw_surface_centered(GRSurface* surface); + // Negative x or y coordinates center text. + virtual int draw_text(const GRFont* font, int x, int y, const char* str); + + // Negative x or y coordinates position the text away from the opposite edge + // that positive ones do. + virtual void determine_xy(const animation::text_field& field, + const int length, int* x, int* y); + + // Draws battery animation, if it exists. + virtual void draw_battery(const animation* anim); + // Draws clock text, if animation contains text_field data. + virtual void draw_clock(const animation* anim); + // Draws battery percentage text if animation contains text_field data. + virtual void draw_percent(const animation* anim); + // Draws charger->surf_unknown or basic text. + virtual void draw_unknown(GRSurface* surf_unknown); + + // Pixel sizes of characters for default font. + int char_width_; + int char_height_; + + // Width and height of screen in pixels. + int screen_width_; + int screen_height_; + + // Device screen is split vertically. + const bool kSplitScreen; + // Pixels to offset graphics towards center split. + const int kSplitOffset; +}; + +#endif // HEALTHD_DRAW_H diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp index c76762d37..6c6d73880 100644 --- a/healthd/healthd_mode_charger.cpp +++ b/healthd/healthd_mode_charger.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 The Android Open Source Project + * Copyright (C) 2011-2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ #include <errno.h> #include <fcntl.h> #include <inttypes.h> -#include <linux/input.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -34,56 +33,54 @@ #include <android-base/file.h> #include <android-base/macros.h> -#include <android-base/stringprintf.h> -#include <sys/socket.h> #include <linux/netlink.h> +#include <sys/socket.h> -#include <batteryservice/BatteryService.h> #include <cutils/klog.h> #include <cutils/misc.h> -#include <cutils/uevent.h> #include <cutils/properties.h> -#include <minui/minui.h> +#include <cutils/uevent.h> #include <sys/reboot.h> #ifdef CHARGER_ENABLE_SUSPEND #include <suspend/autosuspend.h> #endif -#include "animation.h" #include "AnimationParser.h" +#include "healthd_draw.h" #include <healthd/healthd.h> using namespace android; -char *locale; +char* locale; #ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define MSEC_PER_SEC (1000LL) -#define NSEC_PER_MSEC (1000000LL) +#define MSEC_PER_SEC (1000LL) +#define NSEC_PER_MSEC (1000000LL) -#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) -#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) +#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) +#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC) -#define LAST_KMSG_MAX_SZ (32 * 1024) +#define LAST_KMSG_MAX_SZ (32 * 1024) -#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0) -#define LOGW(x...) do { KLOG_WARNING("charger", x); } while (0) -#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0) +#define LOGE(x...) KLOG_ERROR("charger", x); +#define LOGW(x...) KLOG_WARNING("charger", x); +#define LOGV(x...) KLOG_DEBUG("charger", x); -static constexpr const char* animation_desc_path = "/res/values/charger/animation.txt"; +static constexpr const char* animation_desc_path = + "/res/values/charger/animation.txt"; struct key_state { bool pending; @@ -98,34 +95,36 @@ struct charger { int64_t next_key_check; int64_t next_pwr_check; - struct key_state keys[KEY_MAX + 1]; + key_state keys[KEY_MAX + 1]; - struct animation *batt_anim; + animation* batt_anim; GRSurface* surf_unknown; int boot_min_cap; }; -static const struct animation BASE_ANIMATION = { - .text_clock = { - .pos_x = 0, - .pos_y = 0, - - .color_r = 255, - .color_g = 255, - .color_b = 255, - .color_a = 255, - - .font = nullptr, - }, - .text_percent = { - .pos_x = 0, - .pos_y = 0, - - .color_r = 255, - .color_g = 255, - .color_b = 255, - .color_a = 255, - }, +static const animation BASE_ANIMATION = { + .text_clock = + { + .pos_x = 0, + .pos_y = 0, + + .color_r = 255, + .color_g = 255, + .color_b = 255, + .color_a = 255, + + .font = nullptr, + }, + .text_percent = + { + .pos_x = 0, + .pos_y = 0, + + .color_r = 255, + .color_g = 255, + .color_b = 255, + .color_a = 255, + }, .run = false, @@ -141,8 +140,7 @@ static const struct animation BASE_ANIMATION = { .cur_status = BATTERY_STATUS_UNKNOWN, }; - -static struct animation::frame default_animation_frames[] = { +static animation::frame default_animation_frames[] = { { .disp_time = 750, .min_level = 0, @@ -181,35 +179,25 @@ static struct animation::frame default_animation_frames[] = { }, }; -static struct animation battery_animation = BASE_ANIMATION; +static animation battery_animation = BASE_ANIMATION; -static struct charger charger_state; -static struct healthd_config *healthd_config; -static struct android::BatteryProperties *batt_prop; -static int char_width; -static int char_height; -static bool minui_inited; +static charger charger_state; +static healthd_config* healthd_config; +static android::BatteryProperties* batt_prop; +static std::unique_ptr<HealthdDraw> healthd_draw; /* current time in milliseconds */ -static int64_t curr_time_ms(void) -{ - struct timespec tm; +static int64_t curr_time_ms() { + timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); return tm.tv_sec * MSEC_PER_SEC + (tm.tv_nsec / NSEC_PER_MSEC); } -static void clear_screen(void) -{ - gr_color(0, 0, 0, 255); - gr_clear(); -} - #define MAX_KLOG_WRITE_BUF_SZ 256 -static void dump_last_kmsg(void) -{ - char *buf; - char *ptr; +static void dump_last_kmsg(void) { + char* buf; + char* ptr; unsigned sz = 0; int len; @@ -239,11 +227,10 @@ static void dump_last_kmsg(void) while (len > 0) { int cnt = min(len, MAX_KLOG_WRITE_BUF_SZ); char yoink; - char *nl; + char* nl; - nl = (char *)memrchr(ptr, '\n', cnt - 1); - if (nl) - cnt = nl - ptr + 1; + nl = (char*)memrchr(ptr, '\n', cnt - 1); + if (nl) cnt = nl - ptr + 1; yoink = ptr[cnt]; ptr[cnt] = '\0'; @@ -263,241 +250,59 @@ out: } #ifdef CHARGER_ENABLE_SUSPEND -static int request_suspend(bool enable) -{ +static int request_suspend(bool enable) { if (enable) return autosuspend_enable(); else return autosuspend_disable(); } #else -static int request_suspend(bool /*enable*/) -{ +static int request_suspend(bool /*enable*/) { return 0; } #endif -static int draw_text(const char *str, int x, int y) -{ - int str_len_px = gr_measure(gr_sys_font(), str); - - if (x < 0) - x = (gr_fb_width() - str_len_px) / 2; - if (y < 0) - y = (gr_fb_height() - char_height) / 2; - gr_text(gr_sys_font(), x, y, str, 0); - - return y + char_height; -} - -static void android_green(void) -{ - gr_color(0xa4, 0xc6, 0x39, 255); -} - -// Negative x or y coordinates position the text away from the opposite edge that positive ones do. -void determine_xy(const animation::text_field& field, const int length, int* x, int* y) -{ - *x = field.pos_x; - *y = field.pos_y; - - int str_len_px = length * field.font->char_width; - if (field.pos_x == CENTER_VAL) { - *x = (gr_fb_width() - str_len_px) / 2; - } else if (field.pos_x >= 0) { - *x = field.pos_x; - } else { // position from max edge - *x = gr_fb_width() + field.pos_x - str_len_px; - } - - if (field.pos_y == CENTER_VAL) { - *y = (gr_fb_height() - field.font->char_height) / 2; - } else if (field.pos_y >= 0) { - *y = field.pos_y; - } else { // position from max edge - *y = gr_fb_height() + field.pos_y - field.font->char_height; - } -} - -static void draw_clock(const animation& anim) -{ - static constexpr char CLOCK_FORMAT[] = "%H:%M"; - static constexpr int CLOCK_LENGTH = 6; - - const animation::text_field& field = anim.text_clock; - - if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) return; - - time_t rawtime; - time(&rawtime); - struct tm* time_info = localtime(&rawtime); - - char clock_str[CLOCK_LENGTH]; - size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); - if (length != CLOCK_LENGTH - 1) { - LOGE("Could not format time\n"); - return; - } - - int x, y; - determine_xy(field, length, &x, &y); - - LOGV("drawing clock %s %d %d\n", clock_str, x, y); - gr_color(field.color_r, field.color_g, field.color_b, field.color_a); - gr_text(field.font, x, y, clock_str, false); -} - -static void draw_percent(const animation& anim) -{ - 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%%", cur_level); - - int x, y; - determine_xy(field, str.size(), &x, &y); - - LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); - gr_color(field.color_r, field.color_g, field.color_b, field.color_a); - gr_text(field.font, x, y, str.c_str(), false); -} - -/* returns the last y-offset of where the surface ends */ -static int draw_surface_centered(GRSurface* surface) -{ - int w; - int h; - int x; - int y; - - w = gr_get_width(surface); - h = gr_get_height(surface); - x = (gr_fb_width() - w) / 2 ; - y = (gr_fb_height() - h) / 2 ; - - LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); - gr_blit(surface, 0, 0, w, h, x, y); - return y + h; -} - -static void draw_unknown(struct charger *charger) -{ - int y; - if (charger->surf_unknown) { - draw_surface_centered(charger->surf_unknown); - } else { - android_green(); - y = draw_text("Charging!", -1, -1); - draw_text("?\?/100", -1, y + 25); - } -} - -static void draw_battery(const struct charger* charger) -{ - const struct animation& anim = *charger->batt_anim; - const struct animation::frame& frame = anim.frames[anim.cur_frame]; - - if (anim.num_frames != 0) { - draw_surface_centered(frame.surface); - LOGV("drawing frame #%d min_cap=%d time=%d\n", - anim.cur_frame, frame.min_level, - frame.disp_time); - } - draw_clock(anim); - draw_percent(anim); -} - -static void redraw_screen(struct charger *charger) -{ - struct animation *batt_anim = charger->batt_anim; - - clear_screen(); - - /* try to display *something* */ - if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) - draw_unknown(charger); - else - draw_battery(charger); - gr_flip(); -} - -static void kick_animation(struct animation *anim) -{ +static void kick_animation(animation* anim) { anim->run = true; } -static void reset_animation(struct animation *anim) -{ +static void reset_animation(animation* anim) { anim->cur_cycle = 0; anim->cur_frame = 0; anim->run = false; } -static void init_status_display(struct animation* anim) -{ - int res; - - if (!anim->text_clock.font_file.empty()) { - if ((res = - gr_init_font(anim->text_clock.font_file.c_str(), &anim->text_clock.font)) < 0) { - LOGE("Could not load time font (%d)\n", res); - } - } - - if (!anim->text_percent.font_file.empty()) { - if ((res = - gr_init_font(anim->text_percent.font_file.c_str(), &anim->text_percent.font)) < 0) { - LOGE("Could not load percent font (%d)\n", res); - } - } -} - -static void update_screen_state(struct charger *charger, int64_t now) -{ - struct animation *batt_anim = charger->batt_anim; +static void update_screen_state(charger* charger, int64_t now) { + animation* batt_anim = charger->batt_anim; int disp_time; if (!batt_anim->run || now < charger->next_screen_transition) return; - if (!minui_inited) { + if (healthd_draw == nullptr) { if (healthd_config && healthd_config->screen_on) { if (!healthd_config->screen_on(batt_prop)) { LOGV("[%" PRId64 "] leave screen off\n", now); batt_anim->run = false; charger->next_screen_transition = -1; - if (charger->charger_connected) - request_suspend(true); + if (charger->charger_connected) request_suspend(true); return; } } - gr_init(); - gr_font_size(gr_sys_font(), &char_width, &char_height); - init_status_display(batt_anim); + healthd_draw.reset(new HealthdDraw(batt_anim)); #ifndef CHARGER_DISABLE_INIT_BLANK - gr_fb_blank(true); + healthd_draw->blank_screen(true); #endif - minui_inited = true; } /* animation is over, blank screen and leave */ if (batt_anim->num_cycles > 0 && batt_anim->cur_cycle == batt_anim->num_cycles) { reset_animation(batt_anim); charger->next_screen_transition = -1; - gr_fb_blank(true); + healthd_draw->blank_screen(true); LOGV("[%" PRId64 "] animation done\n", now); - if (charger->charger_connected) - request_suspend(true); + if (charger->charger_connected) request_suspend(true); return; } @@ -505,7 +310,6 @@ static void update_screen_state(struct charger *charger, int64_t now) /* animation starting, set up the animation */ if (batt_anim->cur_frame == 0) { - LOGV("[%" PRId64 "] animation starting\n", now); if (batt_prop) { batt_anim->cur_level = batt_prop->batteryLevel; @@ -522,17 +326,16 @@ static void update_screen_state(struct charger *charger, int64_t now) // repeat the first frame first_frame_repeats times disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * - batt_anim->first_frame_repeats; + batt_anim->first_frame_repeats; } } } /* unblank the screen on first cycle */ - if (batt_anim->cur_cycle == 0) - gr_fb_blank(false); + if (batt_anim->cur_cycle == 0) healthd_draw->blank_screen(false); /* draw the new frame (@ cur_frame) */ - redraw_screen(charger); + healthd_draw->redraw_screen(charger->batt_anim, charger->surf_unknown); /* if we don't have anim frames, we only have one image, so just bump * the cycle counter and exit @@ -576,22 +379,18 @@ static void update_screen_state(struct charger *charger, int64_t now) } } -static int set_key_callback(struct charger *charger, int code, int value) -{ +static int set_key_callback(charger* charger, int code, int value) { int64_t now = curr_time_ms(); int down = !!value; - if (code > KEY_MAX) - return -1; + if (code > KEY_MAX) return -1; /* ignore events that don't modify our state */ - if (charger->keys[code].down == down) - return 0; + if (charger->keys[code].down == down) return 0; /* only record the down even timestamp, as the amount * of time the key spent not being pressed is not useful */ - if (down) - charger->keys[code].timestamp = now; + if (down) charger->keys[code].timestamp = now; charger->keys[code].down = down; charger->keys[code].pending = true; if (down) { @@ -600,34 +399,27 @@ static int set_key_callback(struct charger *charger, int code, int value) int64_t duration = now - charger->keys[code].timestamp; int64_t secs = duration / 1000; int64_t msecs = duration - secs * 1000; - LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", - now, code, secs, msecs); + LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", now, code, + secs, msecs); } return 0; } -static void update_input_state(struct charger *charger, - struct input_event *ev) -{ - if (ev->type != EV_KEY) - return; +static void update_input_state(charger* charger, input_event* ev) { + if (ev->type != EV_KEY) return; set_key_callback(charger, ev->code, ev->value); } -static void set_next_key_check(struct charger *charger, - struct key_state *key, - int64_t timeout) -{ +static void set_next_key_check(charger* charger, key_state* key, int64_t timeout) { int64_t then = key->timestamp + timeout; if (charger->next_key_check == -1 || then < charger->next_key_check) charger->next_key_check = then; } -static void process_key(struct charger *charger, int code, int64_t now) -{ - struct key_state *key = &charger->keys[code]; +static void process_key(charger* charger, int code, int64_t now) { + key_state* key = &charger->keys[code]; if (code == KEY_POWER) { if (key->down) { @@ -644,8 +436,10 @@ static void process_key(struct charger *charger, int code, int64_t now) LOGW("[%" PRId64 "] rebooting\n", now); reboot(RB_AUTOBOOT); } else { - LOGV("[%" PRId64 "] ignore power-button press, battery level " - "less than minimum\n", now); + LOGV("[%" PRId64 + "] ignore power-button press, battery level " + "less than minimum\n", + now); } } } else { @@ -654,9 +448,9 @@ static void process_key(struct charger *charger, int code, int64_t now) */ set_next_key_check(charger, key, POWER_ON_KEY_TIME); - /* Turn on the display and kick animation on power-key press - * rather than on key release - */ + /* Turn on the display and kick animation on power-key press + * rather than on key release + */ kick_animation(charger->batt_anim); request_suspend(false); } @@ -671,21 +465,17 @@ static void process_key(struct charger *charger, int code, int64_t now) key->pending = false; } -static void handle_input_state(struct charger *charger, int64_t now) -{ +static void handle_input_state(charger* charger, int64_t now) { process_key(charger, KEY_POWER, now); if (charger->next_key_check != -1 && now > charger->next_key_check) charger->next_key_check = -1; } -static void handle_power_supply_state(struct charger *charger, int64_t now) -{ - if (!charger->have_battery_state) - return; +static void handle_power_supply_state(charger* charger, int64_t now) { + if (!charger->have_battery_state) return; if (!charger->charger_connected) { - /* Last cycle would have stopped at the extreme top of battery-icon * Need to show the correct level corresponding to capacity. */ @@ -711,9 +501,8 @@ static void handle_power_supply_state(struct charger *charger, int64_t now) } } -void healthd_mode_charger_heartbeat() -{ - struct charger *charger = &charger_state; +void healthd_mode_charger_heartbeat() { + charger* charger = &charger_state; int64_t now = curr_time_ms(); handle_input_state(charger, now); @@ -725,14 +514,11 @@ void healthd_mode_charger_heartbeat() update_screen_state(charger, now); } -void healthd_mode_charger_battery_update( - struct android::BatteryProperties *props) -{ - struct charger *charger = &charger_state; +void healthd_mode_charger_battery_update(android::BatteryProperties* props) { + charger* charger = &charger_state; charger->charger_connected = - props->chargerAcOnline || props->chargerUsbOnline || - props->chargerWirelessOnline; + props->chargerAcOnline || props->chargerUsbOnline || props->chargerWirelessOnline; if (!charger->have_battery_state) { charger->have_battery_state = true; @@ -743,19 +529,16 @@ void healthd_mode_charger_battery_update( batt_prop = props; } -int healthd_mode_charger_preparetowait(void) -{ - struct charger *charger = &charger_state; +int healthd_mode_charger_preparetowait(void) { + charger* charger = &charger_state; int64_t now = curr_time_ms(); int64_t next_event = INT64_MAX; int64_t timeout; - LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", now, - charger->next_screen_transition, charger->next_key_check, - charger->next_pwr_check); + LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", + now, charger->next_screen_transition, charger->next_key_check, charger->next_pwr_check); - if (charger->next_screen_transition != -1) - next_event = charger->next_screen_transition; + if (charger->next_screen_transition != -1) next_event = charger->next_screen_transition; if (charger->next_key_check != -1 && charger->next_key_check < next_event) next_event = charger->next_key_check; if (charger->next_pwr_check != -1 && charger->next_pwr_check < next_event) @@ -766,32 +549,27 @@ int healthd_mode_charger_preparetowait(void) else timeout = -1; - return (int)timeout; + return (int)timeout; } -static int input_callback(struct charger *charger, int fd, unsigned int epevents) -{ - struct input_event ev; +static int input_callback(charger* charger, int fd, unsigned int epevents) { + input_event ev; int ret; ret = ev_get_input(fd, epevents, &ev); - if (ret) - return -1; + if (ret) return -1; update_input_state(charger, &ev); return 0; } -static void charger_event_handler(uint32_t /*epevents*/) -{ +static void charger_event_handler(uint32_t /*epevents*/) { int ret; ret = ev_wait(-1); - if (!ret) - ev_dispatch(); + if (!ret) ev_dispatch(); } -animation* init_animation() -{ +animation* init_animation() { bool parse_success; std::string content; @@ -814,32 +592,29 @@ animation* init_animation() } LOGV("Animation Description:\n"); - LOGV(" animation: %d %d '%s' (%d)\n", - battery_animation.num_cycles, battery_animation.first_frame_repeats, - battery_animation.animation_file.c_str(), battery_animation.num_frames); + LOGV(" animation: %d %d '%s' (%d)\n", battery_animation.num_cycles, + battery_animation.first_frame_repeats, battery_animation.animation_file.c_str(), + battery_animation.num_frames); LOGV(" fail_file: '%s'\n", battery_animation.fail_file.c_str()); - LOGV(" clock: %d %d %d %d %d %d '%s'\n", - battery_animation.text_clock.pos_x, battery_animation.text_clock.pos_y, - battery_animation.text_clock.color_r, battery_animation.text_clock.color_g, - battery_animation.text_clock.color_b, battery_animation.text_clock.color_a, - battery_animation.text_clock.font_file.c_str()); - LOGV(" percent: %d %d %d %d %d %d '%s'\n", - battery_animation.text_percent.pos_x, battery_animation.text_percent.pos_y, - battery_animation.text_percent.color_r, battery_animation.text_percent.color_g, - battery_animation.text_percent.color_b, battery_animation.text_percent.color_a, - battery_animation.text_percent.font_file.c_str()); + LOGV(" clock: %d %d %d %d %d %d '%s'\n", battery_animation.text_clock.pos_x, + battery_animation.text_clock.pos_y, battery_animation.text_clock.color_r, + battery_animation.text_clock.color_g, battery_animation.text_clock.color_b, + battery_animation.text_clock.color_a, battery_animation.text_clock.font_file.c_str()); + LOGV(" percent: %d %d %d %d %d %d '%s'\n", battery_animation.text_percent.pos_x, + battery_animation.text_percent.pos_y, battery_animation.text_percent.color_r, + battery_animation.text_percent.color_g, battery_animation.text_percent.color_b, + battery_animation.text_percent.color_a, battery_animation.text_percent.font_file.c_str()); for (int i = 0; i < battery_animation.num_frames; i++) { LOGV(" frame %.2d: %d %d %d\n", i, battery_animation.frames[i].disp_time, - battery_animation.frames[i].min_level, battery_animation.frames[i].max_level); + battery_animation.frames[i].min_level, battery_animation.frames[i].max_level); } return &battery_animation; } -void healthd_mode_charger_init(struct healthd_config* config) -{ +void healthd_mode_charger_init(struct healthd_config* config) { int ret; - struct charger *charger = &charger_state; + charger* charger = &charger_state; int i; int epollfd; @@ -847,14 +622,13 @@ void healthd_mode_charger_init(struct healthd_config* config) LOGW("--------------- STARTING CHARGER MODE ---------------\n"); - ret = ev_init(std::bind(&input_callback, charger, std::placeholders::_1, - std::placeholders::_2)); + ret = ev_init(std::bind(&input_callback, charger, std::placeholders::_1, std::placeholders::_2)); if (!ret) { epollfd = ev_get_epollfd(); healthd_register_event(epollfd, charger_event_handler, EVENT_WAKEUP_FD); } - struct animation* anim = init_animation(); + animation* anim = init_animation(); charger->batt_anim = anim; ret = res_create_display_surface(anim->fail_file.c_str(), &charger->surf_unknown); @@ -871,15 +645,15 @@ void healthd_mode_charger_init(struct healthd_config* config) int scale_count; int scale_fps; // Not in use (charger/battery_scale doesn't have FPS text // chunk). We are using hard-coded frame.disp_time instead. - ret = res_create_multi_display_surface(anim->animation_file.c_str(), - &scale_count, &scale_fps, &scale_frames); + ret = res_create_multi_display_surface(anim->animation_file.c_str(), &scale_count, &scale_fps, + &scale_frames); if (ret < 0) { LOGE("Cannot load battery_scale image\n"); anim->num_frames = 0; anim->num_cycles = 1; } else if (scale_count != anim->num_frames) { - LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", - scale_count, anim->num_frames); + LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", scale_count, + anim->num_frames); anim->num_frames = 0; anim->num_cycles = 1; } else { @@ -887,8 +661,8 @@ void healthd_mode_charger_init(struct healthd_config* config) anim->frames[i].surface = scale_frames[i]; } } - ev_sync_key_state(std::bind(&set_key_callback, charger, std::placeholders::_1, - std::placeholders::_2)); + ev_sync_key_state( + std::bind(&set_key_callback, charger, std::placeholders::_1, std::placeholders::_2)); charger->next_screen_transition = -1; charger->next_key_check = -1; diff --git a/init/builtins.cpp b/init/builtins.cpp index 027b392fd..9be274b56 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -506,6 +506,25 @@ static Result<Success> queue_fs_event(int code) { // do anything different from the nonencrypted case. ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); return Success(); + } else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) { + if (e4crypt_install_keyring()) { + return Error() << "e4crypt_install_keyring() failed"; + } + property_set("ro.crypto.state", "encrypted"); + property_set("ro.crypto.type", "file"); + + // defaultcrypto detects file/block encryption. init flow is same for each. + ActionManager::GetInstance().QueueEventTrigger("defaultcrypto"); + return Success(); + } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { + if (e4crypt_install_keyring()) { + return Error() << "e4crypt_install_keyring() failed"; + } + property_set("ro.crypto.type", "file"); + + // encrypt detects file/block encryption. init flow is same for each. + ActionManager::GetInstance().QueueEventTrigger("encrypt"); + return Success(); } else if (code > 0) { Error() << "fs_mgr_mount_all() returned unexpected error " << code; } diff --git a/init/property_service.cpp b/init/property_service.cpp index 223d34e8a..d70185094 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -514,7 +514,7 @@ static void handle_property_set_fd() { } } -static void load_properties_from_file(const char *, const char *); +static bool load_properties_from_file(const char *, const char *); /* * Filter is used to decide which properties to load: NULL loads all keys, @@ -578,17 +578,18 @@ static void load_properties(char *data, const char *filter) // Filter is used to decide which properties to load: NULL loads all keys, // "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match. -static void load_properties_from_file(const char* filename, const char* filter) { +static bool load_properties_from_file(const char* filename, const char* filter) { Timer t; auto file_contents = ReadFile(filename); if (!file_contents) { PLOG(WARNING) << "Couldn't load property file '" << filename << "': " << file_contents.error(); - return; + return false; } file_contents->push_back('\n'); load_properties(file_contents->data(), filter); LOG(VERBOSE) << "(Loading properties from " << filename << " took " << t << ".)"; + return true; } // persist.sys.usb.config values can't be combined on build-time when property @@ -608,7 +609,13 @@ static void update_sys_usb_config() { } void property_load_boot_defaults() { - load_properties_from_file("/default.prop", NULL); + if (!load_properties_from_file("/system/etc/prop.default", NULL)) { + // Try recovery path + if (!load_properties_from_file("/prop.default", NULL)) { + // Try legacy path + load_properties_from_file("/default.prop", NULL); + } + } load_properties_from_file("/odm/default.prop", NULL); load_properties_from_file("/vendor/default.prop", NULL); diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc index 3f47066a8..07923071b 100644 --- a/libappfuse/FuseBridgeLoop.cc +++ b/libappfuse/FuseBridgeLoop.cc @@ -57,6 +57,12 @@ void GetObservedEvents(FuseBridgeState state, int* device_events, int* proxy_eve return; } } + +void LogResponseError(const std::string& message, const FuseResponse& response) { + LOG(ERROR) << message << ": header.len=" << response.header.len + << " header.error=" << response.header.error + << " header.unique=" << response.header.unique; +} } class FuseBridgeEntry { @@ -135,6 +141,7 @@ class FuseBridgeEntry { } if (!buffer_.response.Write(device_fd_)) { + LogResponseError("Failed to write a reply from proxy to device", buffer_.response); return FuseBridgeState::kClosing; } @@ -200,6 +207,7 @@ class FuseBridgeEntry { } if (!buffer_.response.Write(device_fd_)) { + LogResponseError("Failed to write a response to device", buffer_.response); return FuseBridgeState::kClosing; } @@ -215,6 +223,11 @@ class FuseBridgeEntry { case ResultOrAgain::kSuccess: return FuseBridgeState::kWaitToReadEither; case ResultOrAgain::kFailure: + LOG(ERROR) << "Failed to write a request to proxy:" + << " header.len=" << buffer_.request.header.len + << " header.opcode=" << buffer_.request.header.opcode + << " header.unique=" << buffer_.request.header.unique + << " header.nodeid=" << buffer_.request.header.nodeid; return FuseBridgeState::kClosing; case ResultOrAgain::kAgain: return FuseBridgeState::kWaitToWriteProxy; diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc index 653e96b28..1eab46cb4 100644 --- a/libappfuse/FuseBuffer.cc +++ b/libappfuse/FuseBuffer.cc @@ -115,7 +115,10 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co case EAGAIN: return ResultOrAgain::kAgain; default: - PLOG(ERROR) << "Failed to write a FUSE message"; + PLOG(ERROR) << "Failed to write a FUSE message: " + << "fd=" << fd << " " + << "sockflag=" << sockflag << " " + << "data=" << data; return ResultOrAgain::kFailure; } } @@ -248,7 +251,9 @@ void FuseBuffer::HandleInit() { void FuseBuffer::HandleNotImpl() { LOG(VERBOSE) << "NOTIMPL op=" << request.header.opcode << " uniq=" << request.header.unique << " nid=" << request.header.nodeid; - const uint64_t unique = request.header.unique; + // Add volatile as a workaround for compiler issue which removes the temporary + // variable. + const volatile uint64_t unique = request.header.unique; response.Reset(0, -ENOSYS, unique); } diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp index bab095ede..1d3e5ead8 100644 --- a/libcutils/fs_config.cpp +++ b/libcutils/fs_config.cpp @@ -133,7 +133,8 @@ static const struct fs_path_config android_files[] = { { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" }, { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" }, { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" }, - { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, + { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, // legacy + { 00600, AID_ROOT, AID_ROOT, 0, "system/etc/prop.default" }, { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" }, { 00444, AID_ROOT, AID_ROOT, 0, odm_conf_dir + 1 }, diff --git a/libcutils/include/cutils/native_handle.h b/libcutils/include/cutils/native_handle.h index 55754b5a4..10f5bc094 100644 --- a/libcutils/include/cutils/native_handle.h +++ b/libcutils/include/cutils/native_handle.h @@ -43,6 +43,8 @@ typedef struct native_handle #endif } native_handle_t; +typedef const native_handle_t* buffer_handle_t; + /* * native_handle_close * diff --git a/libcutils/include/cutils/sched_policy.h b/libcutils/include/cutils/sched_policy.h index cf8f5c384..4c1113be3 100644 --- a/libcutils/include/cutils/sched_policy.h +++ b/libcutils/include/cutils/sched_policy.h @@ -47,6 +47,7 @@ typedef enum { SP_AUDIO_APP = 3, SP_AUDIO_SYS = 4, SP_TOP_APP = 5, + SP_RT_APP = 6, SP_CNT, SP_MAX = SP_CNT - 1, SP_SYSTEM_DEFAULT = SP_FOREGROUND, diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp index f733e9036..b00fa8561 100644 --- a/libcutils/sched_policy.cpp +++ b/libcutils/sched_policy.cpp @@ -63,6 +63,7 @@ static int ta_cpuset_fd = -1; // special cpuset for top app static int bg_schedboost_fd = -1; static int fg_schedboost_fd = -1; static int ta_schedboost_fd = -1; +static int rt_schedboost_fd = -1; /* Add tid to the scheduling group defined by the policy */ static int add_tid_to_cgroup(int tid, int fd) @@ -159,6 +160,8 @@ static void __initialize() { fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC); filename = "/dev/stune/background/tasks"; bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC); + filename = "/dev/stune/rt/tasks"; + rt_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC); } } } @@ -394,6 +397,9 @@ int set_sched_policy(int tid, SchedPolicy policy) case SP_SYSTEM: SLOGD("/// tid %d (%s)", tid, thread_name); break; + case SP_RT_APP: + SLOGD("RT tid %d (%s)", tid, thread_name); + break; default: SLOGD("??? tid %d (%s)", tid, thread_name); break; @@ -414,6 +420,9 @@ int set_sched_policy(int tid, SchedPolicy policy) case SP_TOP_APP: boost_fd = ta_schedboost_fd; break; + case SP_RT_APP: + boost_fd = rt_schedboost_fd; + break; default: boost_fd = -1; break; @@ -458,6 +467,7 @@ const char *get_sched_policy_name(SchedPolicy policy) [SP_AUDIO_APP] = "aa", [SP_AUDIO_SYS] = "as", [SP_TOP_APP] = "ta", + [SP_RT_APP] = "rt", }; if ((policy < SP_CNT) && (strings[policy] != NULL)) return strings[policy]; diff --git a/liblog/Android.bp b/liblog/Android.bp index d5bb29ed0..6584c952d 100644 --- a/liblog/Android.bp +++ b/liblog/Android.bp @@ -42,24 +42,6 @@ liblog_target_sources = [ "logd_writer.c", ] -cc_library_headers { - name: "liblog_headers", - host_supported: true, - vendor_available: true, - export_include_dirs: ["include"], - target: { - windows: { - enabled: true, - }, - linux_bionic: { - enabled: true, - }, - vendor: { - export_include_dirs: ["include_vndk"], - }, - }, -} - // Shared and static library for host and device // ======================================================== cc_library { @@ -96,8 +78,7 @@ cc_library { }, }, - header_libs: ["liblog_headers"], - export_header_lib_headers: ["liblog_headers"], + export_include_dirs: ["include"], cflags: [ "-Werror", @@ -116,7 +97,7 @@ cc_library { } ndk_headers { - name: "liblog_ndk_headers", + name: "liblog_headers", from: "include/android", to: "android", srcs: ["include/android/log.h"], diff --git a/libsuspend/autosuspend_wakeup_count.c b/libsuspend/autosuspend_wakeup_count.c index 4dedf7f9f..2da204ae0 100644 --- a/libsuspend/autosuspend_wakeup_count.c +++ b/libsuspend/autosuspend_wakeup_count.c @@ -24,6 +24,7 @@ #include <stddef.h> #include <stdbool.h> #include <string.h> +#include <sys/param.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -35,12 +36,24 @@ #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))) { @@ -48,10 +61,12 @@ static void *suspend_thread_func(void *arg __attribute__((unused))) char wakeup_count[20]; int wakeup_count_len; int ret; - bool success; + bool success = true; while (1) { - usleep(100000); + update_sleep_time(success); + usleep(sleep_time); + success = false; 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, @@ -75,7 +90,6 @@ static void *suspend_thread_func(void *arg __attribute__((unused))) 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) { @@ -84,8 +98,8 @@ static void *suspend_thread_func(void *arg __attribute__((unused))) } 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 = false; + if (ret >= 0) { + success = true; } void (*func)(bool success) = wakeup_func; if (func != NULL) { diff --git a/libsystem/include/system/qemu_pipe.h b/libsystem/include/system/qemu_pipe.h deleted file mode 100644 index af2507997..000000000 --- a/libsystem/include/system/qemu_pipe.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef ANDROID_INCLUDE_SYSTEM_QEMU_PIPE_H -#define ANDROID_INCLUDE_SYSTEM_QEMU_PIPE_H - -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> - -// Define QEMU_PIPE_DEBUG if you want to print error messages when an error -// occurs during pipe operations. The macro should simply take a printf-style -// formatting string followed by optional arguments. -#ifndef QEMU_PIPE_DEBUG -# define QEMU_PIPE_DEBUG(...) (void)0 -#endif - -// Try to open a new Qemu fast-pipe. This function returns a file descriptor -// that can be used to communicate with a named service managed by the -// emulator. -// -// This file descriptor can be used as a standard pipe/socket descriptor. -// -// 'pipeName' is the name of the emulator service you want to connect to, -// and must begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles'). -// -// On success, return a valid file descriptor, or -1/errno on failure. E.g.: -// -// EINVAL -> unknown/unsupported pipeName -// ENOSYS -> fast pipes not available in this system. -// -// ENOSYS should never happen, except if you're trying to run within a -// misconfigured emulator. -// -// You should be able to open several pipes to the same pipe service, -// except for a few special cases (e.g. GSM modem), where EBUSY will be -// returned if more than one client tries to connect to it. -static __inline__ int qemu_pipe_open(const char* pipeName) { - // Sanity check. - if (!pipeName || memcmp(pipeName, "pipe:", 5) != 0) { - errno = EINVAL; - return -1; - } - - int fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR)); - if (fd < 0) { - QEMU_PIPE_DEBUG("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, - strerror(errno)); - return -1; - } - - // Write the pipe name, *including* the trailing zero which is necessary. - size_t pipeNameLen = strlen(pipeName); - ssize_t ret = TEMP_FAILURE_RETRY(write(fd, pipeName, pipeNameLen + 1U)); - if (ret != (ssize_t)pipeNameLen + 1) { - QEMU_PIPE_DEBUG("%s: Could not connect to %s pipe service: %s", - __FUNCTION__, pipeName, strerror(errno)); - if (ret == 0) { - errno = ECONNRESET; - } else if (ret > 0) { - errno = EINVAL; - } - return -1; - } - return fd; -} - -// Send a framed message |buff| of |len| bytes through the |fd| descriptor. -// This really adds a 4-hexchar prefix describing the payload size. -// Returns 0 on success, and -1 on error. -static int __inline__ qemu_pipe_frame_send(int fd, - const void* buff, - size_t len) { - char header[5]; - snprintf(header, sizeof(header), "%04zx", len); - ssize_t ret = TEMP_FAILURE_RETRY(write(fd, header, 4)); - if (ret != 4) { - QEMU_PIPE_DEBUG("Can't write qemud frame header: %s", strerror(errno)); - return -1; - } - ret = TEMP_FAILURE_RETRY(write(fd, buff, len)); - if (ret != (ssize_t)len) { - QEMU_PIPE_DEBUG("Can't write qemud frame payload: %s", strerror(errno)); - return -1; - } - return 0; -} - -// Read a frame message from |fd|, and store it into |buff| of |len| bytes. -// If the framed message is larger than |len|, then this returns -1 and the -// content is lost. Otherwise, this returns the size of the message. NOTE: -// empty messages are possible in a framed wire protocol and do not mean -// end-of-stream. -static int __inline__ qemu_pipe_frame_recv(int fd, void* buff, size_t len) { - char header[5]; - ssize_t ret = TEMP_FAILURE_RETRY(read(fd, header, 4)); - if (ret != 4) { - QEMU_PIPE_DEBUG("Can't read qemud frame header: %s", strerror(errno)); - return -1; - } - header[4] = '\0'; - size_t size; - if (sscanf(header, "%04zx", &size) != 1) { - QEMU_PIPE_DEBUG("Malformed qemud frame header: [%.*s]", 4, header); - return -1; - } - if (size > len) { - QEMU_PIPE_DEBUG("Oversized qemud frame (% bytes, expected <= %)", size, - len); - return -1; - } - ret = TEMP_FAILURE_RETRY(read(fd, buff, size)); - if (ret != (ssize_t)size) { - QEMU_PIPE_DEBUG("Could not read qemud frame payload: %s", - strerror(errno)); - return -1; - } - return size; -} - -#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */ diff --git a/libsystem/include/system/window-deprecated.h b/libsystem/include/system/window-deprecated.h deleted file mode 100644 index e836aea94..000000000 --- a/libsystem/include/system/window-deprecated.h +++ /dev/null @@ -1,1114 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/************************************************************************************************** - ************************************************************************************************** - **** **** - **** DEPRECATED **** - **** **** - **** THIS FILE EXISTS ONLY FOR BACKWARD SOURCE COMPATIBILITY. **** - **** **** - **** DO NOT ADD TO THIS FILE. **** - **** **** - **** Driver implementors (vendors) should use vndk/window.h **** - **** (frameworks/native/libs/nativewindow/include/vndk/window.h) **** - **** **** - **** Internal definition can be found here: **** - **** frameworks/native/libs/nativewindow/include/system/window.h **** - **** **** - ************************************************************************************************** - **************************************************************************************************/ - -#pragma once - -#include <cutils/native_handle.h> -#include <errno.h> -#include <limits.h> -#include <stdint.h> -#include <string.h> -#include <sys/cdefs.h> -#include <system/graphics.h> -#include <unistd.h> -#include <stdbool.h> - -#ifndef __UNUSED -#define __UNUSED __attribute__((__unused__)) -#endif -#ifndef __deprecated -#define __deprecated __attribute__((__deprecated__)) -#endif - -__BEGIN_DECLS - -/*****************************************************************************/ - -#ifdef __cplusplus -#define ANDROID_NATIVE_UNSIGNED_CAST(x) static_cast<unsigned int>(x) -#else -#define ANDROID_NATIVE_UNSIGNED_CAST(x) ((unsigned int)(x)) -#endif - -#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \ - ((ANDROID_NATIVE_UNSIGNED_CAST(a) << 24) | \ - (ANDROID_NATIVE_UNSIGNED_CAST(b) << 16) | \ - (ANDROID_NATIVE_UNSIGNED_CAST(c) << 8) | \ - (ANDROID_NATIVE_UNSIGNED_CAST(d))) - -#define ANDROID_NATIVE_WINDOW_MAGIC \ - ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d') - -#define ANDROID_NATIVE_BUFFER_MAGIC \ - ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r') - -// --------------------------------------------------------------------------- - -// This #define may be used to conditionally compile device-specific code to -// support either the prior ANativeWindow interface, which did not pass libsync -// fences around, or the new interface that does. This #define is only present -// when the ANativeWindow interface does include libsync support. -#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1 - -// --------------------------------------------------------------------------- - -typedef const native_handle_t* buffer_handle_t; - -// --------------------------------------------------------------------------- - -typedef struct android_native_rect_t -{ - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -} android_native_rect_t; - -// --------------------------------------------------------------------------- - -typedef struct android_native_base_t -{ - /* a magic value defined by the actual EGL native type */ - int magic; - - /* the sizeof() of the actual EGL native type */ - int version; - - void* reserved[4]; - - /* reference-counting interface */ - void (*incRef)(struct android_native_base_t* base); - void (*decRef)(struct android_native_base_t* base); -} android_native_base_t; - -typedef struct ANativeWindowBuffer -{ -#ifdef __cplusplus - ANativeWindowBuffer() { - common.magic = ANDROID_NATIVE_BUFFER_MAGIC; - common.version = sizeof(ANativeWindowBuffer); - memset(common.reserved, 0, sizeof(common.reserved)); - } - - // Implement the methods that sp<ANativeWindowBuffer> expects so that it - // can be used to automatically refcount ANativeWindowBuffer's. - void incStrong(const void* /*id*/) const { - common.incRef(const_cast<android_native_base_t*>(&common)); - } - void decStrong(const void* /*id*/) const { - common.decRef(const_cast<android_native_base_t*>(&common)); - } -#endif - - struct android_native_base_t common; - - int width; - int height; - int stride; - int format; - int usage; - uintptr_t layerCount; - - void* reserved[1]; - - buffer_handle_t handle; - - void* reserved_proc[8]; -} ANativeWindowBuffer_t; - -// Old typedef for backwards compatibility. -typedef ANativeWindowBuffer_t android_native_buffer_t; - -// --------------------------------------------------------------------------- - -/* attributes queriable with query() */ -enum { - NATIVE_WINDOW_WIDTH = 0, - NATIVE_WINDOW_HEIGHT = 1, - NATIVE_WINDOW_FORMAT = 2, - - /* The minimum number of buffers that must remain un-dequeued after a buffer - * has been queued. This value applies only if set_buffer_count was used to - * override the number of buffers and if a buffer has since been queued. - * Users of the set_buffer_count ANativeWindow method should query this - * value before calling set_buffer_count. If it is necessary to have N - * buffers simultaneously dequeued as part of the steady-state operation, - * and this query returns M then N+M buffers should be requested via - * native_window_set_buffer_count. - * - * Note that this value does NOT apply until a single buffer has been - * queued. In particular this means that it is possible to: - * - * 1. Query M = min undequeued buffers - * 2. Set the buffer count to N + M - * 3. Dequeue all N + M buffers - * 4. Cancel M buffers - * 5. Queue, dequeue, queue, dequeue, ad infinitum - */ - NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = 3, - - /* Check whether queueBuffer operations on the ANativeWindow send the buffer - * to the window compositor. The query sets the returned 'value' argument - * to 1 if the ANativeWindow DOES send queued buffers directly to the window - * compositor and 0 if the buffers do not go directly to the window - * compositor. - * - * This can be used to determine whether protected buffer content should be - * sent to the ANativeWindow. Note, however, that a result of 1 does NOT - * indicate that queued buffers will be protected from applications or users - * capturing their contents. If that behavior is desired then some other - * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in - * conjunction with this query. - */ - NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER = 4, - - /* Get the concrete type of a ANativeWindow. See below for the list of - * possible return values. - * - * This query should not be used outside the Android framework and will - * likely be removed in the near future. - */ - NATIVE_WINDOW_CONCRETE_TYPE = 5, - - - /* - * Default width and height of ANativeWindow buffers, these are the - * dimensions of the window buffers irrespective of the - * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window - * size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS. - */ - NATIVE_WINDOW_DEFAULT_WIDTH = 6, - NATIVE_WINDOW_DEFAULT_HEIGHT = 7, - - /* - * transformation that will most-likely be applied to buffers. This is only - * a hint, the actual transformation applied might be different. - * - * INTENDED USE: - * - * The transform hint can be used by a producer, for instance the GLES - * driver, to pre-rotate the rendering such that the final transformation - * in the composer is identity. This can be very useful when used in - * conjunction with the h/w composer HAL, in situations where it - * cannot handle arbitrary rotations. - * - * 1. Before dequeuing a buffer, the GL driver (or any other ANW client) - * queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT. - * - * 2. The GL driver overrides the width and height of the ANW to - * account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying - * NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions - * according to NATIVE_WINDOW_TRANSFORM_HINT and calling - * native_window_set_buffers_dimensions(). - * - * 3. The GL driver dequeues a buffer of the new pre-rotated size. - * - * 4. The GL driver renders to the buffer such that the image is - * already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT - * to the rendering. - * - * 5. The GL driver calls native_window_set_transform to apply - * inverse transformation to the buffer it just rendered. - * In order to do this, the GL driver needs - * to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is - * done easily: - * - * int hintTransform, inverseTransform; - * query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform); - * inverseTransform = hintTransform; - * if (hintTransform & HAL_TRANSFORM_ROT_90) - * inverseTransform ^= HAL_TRANSFORM_ROT_180; - * - * - * 6. The GL driver queues the pre-transformed buffer. - * - * 7. The composer combines the buffer transform with the display - * transform. If the buffer transform happens to cancel out the - * display transform then no rotation is needed. - * - */ - NATIVE_WINDOW_TRANSFORM_HINT = 8, - - /* - * Boolean that indicates whether the consumer is running more than - * one buffer behind the producer. - */ - NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND = 9, - - /* - * The consumer gralloc usage bits currently set by the consumer. - * The values are defined in hardware/libhardware/include/gralloc.h. - */ - NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10, - - /** - * Transformation that will by applied to buffers by the hwcomposer. - * This must not be set or checked by producer endpoints, and will - * disable the transform hint set in SurfaceFlinger (see - * NATIVE_WINDOW_TRANSFORM_HINT). - * - * INTENDED USE: - * Temporary - Please do not use this. This is intended only to be used - * by the camera's LEGACY mode. - * - * In situations where a SurfaceFlinger client wishes to set a transform - * that is not visible to the producer, and will always be applied in the - * hardware composer, the client can set this flag with - * native_window_set_buffers_sticky_transform. This can be used to rotate - * and flip buffers consumed by hardware composer without actually changing - * the aspect ratio of the buffers produced. - */ - NATIVE_WINDOW_STICKY_TRANSFORM = 11, - - /** - * The default data space for the buffers as set by the consumer. - * The values are defined in graphics.h. - */ - NATIVE_WINDOW_DEFAULT_DATASPACE = 12, - - /* - * Returns the age of the contents of the most recently dequeued buffer as - * the number of frames that have elapsed since it was last queued. For - * example, if the window is double-buffered, the age of any given buffer in - * steady state will be 2. If the dequeued buffer has never been queued, its - * age will be 0. - */ - NATIVE_WINDOW_BUFFER_AGE = 13, - - /* - * Returns the duration of the last dequeueBuffer call in microseconds - */ - NATIVE_WINDOW_LAST_DEQUEUE_DURATION = 14, - - /* - * Returns the duration of the last queueBuffer call in microseconds - */ - NATIVE_WINDOW_LAST_QUEUE_DURATION = 15, - - /* - * Returns the number of image layers that the ANativeWindow buffer - * contains. By default this is 1, unless a buffer is explicitly allocated - * to contain multiple layers. - */ - NATIVE_WINDOW_LAYER_COUNT = 16, - - /* - * Returns 1 if the native window is valid, 0 otherwise. native window is valid - * if it is safe (i.e. no crash will occur) to call any method on it. - */ - NATIVE_WINDOW_IS_VALID = 17, - - /* - * Returns 1 if NATIVE_WINDOW_GET_FRAME_TIMESTAMPS will return display - * present info, 0 if it won't. - */ - NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT = 18, - - /* - * The consumer end is capable of handling protected buffers, i.e. buffer - * with GRALLOC_USAGE_PROTECTED usage bits on. - */ - NATIVE_WINDOW_CONSUMER_IS_PROTECTED = 19, -}; - -/* Valid operations for the (*perform)() hook. - * - * Values marked as 'deprecated' are supported, but have been superceded by - * other functionality. - * - * Values marked as 'private' should be considered private to the framework. - * HAL implementation code with access to an ANativeWindow should not use these, - * as it may not interact properly with the framework's use of the - * ANativeWindow. - */ -enum { -// clang-format off - NATIVE_WINDOW_SET_USAGE = 0, - NATIVE_WINDOW_CONNECT = 1, /* deprecated */ - NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */ - NATIVE_WINDOW_SET_CROP = 3, /* private */ - NATIVE_WINDOW_SET_BUFFER_COUNT = 4, - NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */ - NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6, - NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7, - NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8, - NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9, - NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */ - NATIVE_WINDOW_LOCK = 11, /* private */ - NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */ - NATIVE_WINDOW_API_CONNECT = 13, /* private */ - NATIVE_WINDOW_API_DISCONNECT = 14, /* private */ - NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */ - NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */ - NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */ - NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18, - NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19, - NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */ - NATIVE_WINDOW_SET_SHARED_BUFFER_MODE = 21, - NATIVE_WINDOW_SET_AUTO_REFRESH = 22, - NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION= 23, - NATIVE_WINDOW_GET_NEXT_FRAME_ID = 24, - NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS = 25, - NATIVE_WINDOW_GET_COMPOSITOR_TIMING = 26, - NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27, - NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28, - NATIVE_WINDOW_GET_HDR_SUPPORT = 29, -// clang-format on -}; - -/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ -enum { - /* Buffers will be queued by EGL via eglSwapBuffers after being filled using - * OpenGL ES. - */ - NATIVE_WINDOW_API_EGL = 1, - - /* Buffers will be queued after being filled using the CPU - */ - NATIVE_WINDOW_API_CPU = 2, - - /* Buffers will be queued by Stagefright after being filled by a video - * decoder. The video decoder can either be a software or hardware decoder. - */ - NATIVE_WINDOW_API_MEDIA = 3, - - /* Buffers will be queued by the the camera HAL. - */ - NATIVE_WINDOW_API_CAMERA = 4, -}; - -/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ -enum { - /* flip source image horizontally */ - NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H , - /* flip source image vertically */ - NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, - /* rotate source image 90 degrees clock-wise, and is applied after TRANSFORM_FLIP_{H|V} */ - NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, - /* rotate source image 180 degrees */ - NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, - /* rotate source image 270 degrees clock-wise */ - NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, - /* transforms source by the inverse transform of the screen it is displayed onto. This - * transform is applied last */ - NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY = 0x08 -}; - -/* parameter for NATIVE_WINDOW_SET_SCALING_MODE - * keep in sync with Surface.java in frameworks/base */ -enum { - /* the window content is not updated (frozen) until a buffer of - * the window size is received (enqueued) - */ - NATIVE_WINDOW_SCALING_MODE_FREEZE = 0, - /* the buffer is scaled in both dimensions to match the window size */ - NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1, - /* the buffer is scaled uniformly such that the smaller dimension - * of the buffer matches the window size (cropping in the process) - */ - NATIVE_WINDOW_SCALING_MODE_SCALE_CROP = 2, - /* the window is clipped to the size of the buffer's crop rectangle; pixels - * outside the crop rectangle are treated as if they are completely - * transparent. - */ - NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP = 3, -}; - -/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */ -enum { - NATIVE_WINDOW_FRAMEBUFFER = 0, /* FramebufferNativeWindow */ - NATIVE_WINDOW_SURFACE = 1, /* Surface */ -}; - -/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP - * - * Special timestamp value to indicate that timestamps should be auto-generated - * by the native window when queueBuffer is called. This is equal to INT64_MIN, - * defined directly to avoid problems with C99/C++ inclusion of stdint.h. - */ -static const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1); - -/* parameter for NATIVE_WINDOW_GET_FRAME_TIMESTAMPS - * - * Special timestamp value to indicate the timestamps aren't yet known or - * that they are invalid. - */ -static const int64_t NATIVE_WINDOW_TIMESTAMP_PENDING = -2; -static const int64_t NATIVE_WINDOW_TIMESTAMP_INVALID = -1; - -struct ANativeWindow -{ -#ifdef __cplusplus - ANativeWindow() - : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) - { - common.magic = ANDROID_NATIVE_WINDOW_MAGIC; - common.version = sizeof(ANativeWindow); - memset(common.reserved, 0, sizeof(common.reserved)); - } - - /* Implement the methods that sp<ANativeWindow> expects so that it - can be used to automatically refcount ANativeWindow's. */ - void incStrong(const void* /*id*/) const { - common.incRef(const_cast<android_native_base_t*>(&common)); - } - void decStrong(const void* /*id*/) const { - common.decRef(const_cast<android_native_base_t*>(&common)); - } -#endif - - struct android_native_base_t common; - - /* flags describing some attributes of this surface or its updater */ - const uint32_t flags; - - /* min swap interval supported by this updated */ - const int minSwapInterval; - - /* max swap interval supported by this updated */ - const int maxSwapInterval; - - /* horizontal and vertical resolution in DPI */ - const float xdpi; - const float ydpi; - - /* Some storage reserved for the OEM's driver. */ - intptr_t oem[4]; - - /* - * Set the swap interval for this surface. - * - * Returns 0 on success or -errno on error. - */ - int (*setSwapInterval)(struct ANativeWindow* window, - int interval); - - /* - * Hook called by EGL to acquire a buffer. After this call, the buffer - * is not locked, so its content cannot be modified. This call may block if - * no buffers are available. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * Returns 0 on success or -errno on error. - * - * XXX: This function is deprecated. It will continue to work for some - * time for binary compatibility, but the new dequeueBuffer function that - * outputs a fence file descriptor should be used in its place. - */ - int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window, - struct ANativeWindowBuffer** buffer); - - /* - * hook called by EGL to lock a buffer. This MUST be called before modifying - * the content of a buffer. The buffer must have been acquired with - * dequeueBuffer first. - * - * Returns 0 on success or -errno on error. - * - * XXX: This function is deprecated. It will continue to work for some - * time for binary compatibility, but it is essentially a no-op, and calls - * to it should be removed. - */ - int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window, - struct ANativeWindowBuffer* buffer); - - /* - * Hook called by EGL when modifications to the render buffer are done. - * This unlocks and post the buffer. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * Buffers MUST be queued in the same order than they were dequeued. - * - * Returns 0 on success or -errno on error. - * - * XXX: This function is deprecated. It will continue to work for some - * time for binary compatibility, but the new queueBuffer function that - * takes a fence file descriptor should be used in its place (pass a value - * of -1 for the fence file descriptor if there is no valid one to pass). - */ - int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window, - struct ANativeWindowBuffer* buffer); - - /* - * hook used to retrieve information about the native window. - * - * Returns 0 on success or -errno on error. - */ - int (*query)(const struct ANativeWindow* window, - int what, int* value); - - /* - * hook used to perform various operations on the surface. - * (*perform)() is a generic mechanism to add functionality to - * ANativeWindow while keeping backward binary compatibility. - * - * DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions - * defined below. - * - * (*perform)() returns -ENOENT if the 'what' parameter is not supported - * by the surface's implementation. - * - * See above for a list of valid operations, such as - * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT - */ - int (*perform)(struct ANativeWindow* window, - int operation, ... ); - - /* - * Hook used to cancel a buffer that has been dequeued. - * No synchronization is performed between dequeue() and cancel(), so - * either external synchronization is needed, or these functions must be - * called from the same thread. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * XXX: This function is deprecated. It will continue to work for some - * time for binary compatibility, but the new cancelBuffer function that - * takes a fence file descriptor should be used in its place (pass a value - * of -1 for the fence file descriptor if there is no valid one to pass). - */ - int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window, - struct ANativeWindowBuffer* buffer); - - /* - * Hook called by EGL to acquire a buffer. This call may block if no - * buffers are available. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * The libsync fence file descriptor returned in the int pointed to by the - * fenceFd argument will refer to the fence that must signal before the - * dequeued buffer may be written to. A value of -1 indicates that the - * caller may access the buffer immediately without waiting on a fence. If - * a valid file descriptor is returned (i.e. any value except -1) then the - * caller is responsible for closing the file descriptor. - * - * Returns 0 on success or -errno on error. - */ - int (*dequeueBuffer)(struct ANativeWindow* window, - struct ANativeWindowBuffer** buffer, int* fenceFd); - - /* - * Hook called by EGL when modifications to the render buffer are done. - * This unlocks and post the buffer. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * The fenceFd argument specifies a libsync fence file descriptor for a - * fence that must signal before the buffer can be accessed. If the buffer - * can be accessed immediately then a value of -1 should be used. The - * caller must not use the file descriptor after it is passed to - * queueBuffer, and the ANativeWindow implementation is responsible for - * closing it. - * - * Returns 0 on success or -errno on error. - */ - int (*queueBuffer)(struct ANativeWindow* window, - struct ANativeWindowBuffer* buffer, int fenceFd); - - /* - * Hook used to cancel a buffer that has been dequeued. - * No synchronization is performed between dequeue() and cancel(), so - * either external synchronization is needed, or these functions must be - * called from the same thread. - * - * The window holds a reference to the buffer between dequeueBuffer and - * either queueBuffer or cancelBuffer, so clients only need their own - * reference if they might use the buffer after queueing or canceling it. - * Holding a reference to a buffer after queueing or canceling it is only - * allowed if a specific buffer count has been set. - * - * The fenceFd argument specifies a libsync fence file decsriptor for a - * fence that must signal before the buffer can be accessed. If the buffer - * can be accessed immediately then a value of -1 should be used. - * - * Note that if the client has not waited on the fence that was returned - * from dequeueBuffer, that same fence should be passed to cancelBuffer to - * ensure that future uses of the buffer are preceded by a wait on that - * fence. The caller must not use the file descriptor after it is passed - * to cancelBuffer, and the ANativeWindow implementation is responsible for - * closing it. - * - * Returns 0 on success or -errno on error. - */ - int (*cancelBuffer)(struct ANativeWindow* window, - struct ANativeWindowBuffer* buffer, int fenceFd); -}; - - /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C). - * android_native_window_t is deprecated. - */ -typedef struct ANativeWindow ANativeWindow; -typedef struct ANativeWindow android_native_window_t __deprecated; - -/* - * native_window_set_usage(..., usage) - * Sets the intended usage flags for the next buffers - * acquired with (*lockBuffer)() and on. - * By default (if this function is never called), a usage of - * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE - * is assumed. - * Calling this function will usually cause following buffers to be - * reallocated. - */ - -static inline int native_window_set_usage( - struct ANativeWindow* window, int usage) -{ - return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage); -} - -/* deprecated. Always returns 0. Don't call. */ -static inline int native_window_connect( - struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; - -static inline int native_window_connect( - struct ANativeWindow* window __UNUSED, int api __UNUSED) { - return 0; -} - -/* deprecated. Always returns 0. Don't call. */ -static inline int native_window_disconnect( - struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; - -static inline int native_window_disconnect( - struct ANativeWindow* window __UNUSED, int api __UNUSED) { - return 0; -} - -/* - * native_window_set_crop(..., crop) - * Sets which region of the next queued buffers needs to be considered. - * Depending on the scaling mode, a buffer's crop region is scaled and/or - * cropped to match the surface's size. This function sets the crop in - * pre-transformed buffer pixel coordinates. - * - * The specified crop region applies to all buffers queued after it is called. - * - * If 'crop' is NULL, subsequently queued buffers won't be cropped. - * - * An error is returned if for instance the crop region is invalid, out of the - * buffer's bound or if the window is invalid. - */ -static inline int native_window_set_crop( - struct ANativeWindow* window, - android_native_rect_t const * crop) -{ - return window->perform(window, NATIVE_WINDOW_SET_CROP, crop); -} - -/* - * native_window_set_post_transform_crop(..., crop) - * Sets which region of the next queued buffers needs to be considered. - * Depending on the scaling mode, a buffer's crop region is scaled and/or - * cropped to match the surface's size. This function sets the crop in - * post-transformed pixel coordinates. - * - * The specified crop region applies to all buffers queued after it is called. - * - * If 'crop' is NULL, subsequently queued buffers won't be cropped. - * - * An error is returned if for instance the crop region is invalid, out of the - * buffer's bound or if the window is invalid. - */ -static inline int native_window_set_post_transform_crop( - struct ANativeWindow* window, - android_native_rect_t const * crop) -{ - return window->perform(window, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP, crop); -} - -/* - * native_window_set_active_rect(..., active_rect) - * - * This function is deprecated and will be removed soon. For now it simply - * sets the post-transform crop for compatibility while multi-project commits - * get checked. - */ -static inline int native_window_set_active_rect( - struct ANativeWindow* window, - android_native_rect_t const * active_rect) __deprecated; - -static inline int native_window_set_active_rect( - struct ANativeWindow* window, - android_native_rect_t const * active_rect) -{ - return native_window_set_post_transform_crop(window, active_rect); -} - -/* - * native_window_set_buffer_count(..., count) - * Sets the number of buffers associated with this native window. - */ -static inline int native_window_set_buffer_count( - struct ANativeWindow* window, - size_t bufferCount) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount); -} - -/* - * native_window_set_buffers_geometry(..., int w, int h, int format) - * All buffers dequeued after this call will have the dimensions and format - * specified. A successful call to this function has the same effect as calling - * native_window_set_buffers_size and native_window_set_buffers_format. - * - * XXX: This function is deprecated. The native_window_set_buffers_dimensions - * and native_window_set_buffers_format functions should be used instead. - */ -static inline int native_window_set_buffers_geometry( - struct ANativeWindow* window, - int w, int h, int format) __deprecated; - -static inline int native_window_set_buffers_geometry( - struct ANativeWindow* window, - int w, int h, int format) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, - w, h, format); -} - -/* - * native_window_set_buffers_dimensions(..., int w, int h) - * All buffers dequeued after this call will have the dimensions specified. - * In particular, all buffers will have a fixed-size, independent from the - * native-window size. They will be scaled according to the scaling mode - * (see native_window_set_scaling_mode) upon window composition. - * - * If w and h are 0, the normal behavior is restored. That is, dequeued buffers - * following this call will be sized to match the window's size. - * - * Calling this function will reset the window crop to a NULL value, which - * disables cropping of the buffers. - */ -static inline int native_window_set_buffers_dimensions( - struct ANativeWindow* window, - int w, int h) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS, - w, h); -} - -/* - * native_window_set_buffers_user_dimensions(..., int w, int h) - * - * Sets the user buffer size for the window, which overrides the - * window's size. All buffers dequeued after this call will have the - * dimensions specified unless overridden by - * native_window_set_buffers_dimensions. All buffers will have a - * fixed-size, independent from the native-window size. They will be - * scaled according to the scaling mode (see - * native_window_set_scaling_mode) upon window composition. - * - * If w and h are 0, the normal behavior is restored. That is, the - * default buffer size will match the windows's size. - * - * Calling this function will reset the window crop to a NULL value, which - * disables cropping of the buffers. - */ -static inline int native_window_set_buffers_user_dimensions( - struct ANativeWindow* window, - int w, int h) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS, - w, h); -} - -/* - * native_window_set_buffers_format(..., int format) - * All buffers dequeued after this call will have the format specified. - * - * If the specified format is 0, the default buffer format will be used. - */ -static inline int native_window_set_buffers_format( - struct ANativeWindow* window, - int format) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format); -} - -/* - * native_window_set_buffers_data_space(..., int dataSpace) - * All buffers queued after this call will be associated with the dataSpace - * parameter specified. - * - * dataSpace specifies additional information about the buffer that's dependent - * on the buffer format and the endpoints. For example, it can be used to convey - * the color space of the image data in the buffer, or it can be used to - * indicate that the buffers contain depth measurement data instead of color - * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been - * overridden by the consumer. - */ -static inline int native_window_set_buffers_data_space( - struct ANativeWindow* window, - android_dataspace_t dataSpace) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE, - dataSpace); -} - -/* - * native_window_set_buffers_transform(..., int transform) - * All buffers queued after this call will be displayed transformed according - * to the transform parameter specified. - */ -static inline int native_window_set_buffers_transform( - struct ANativeWindow* window, - int transform) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, - transform); -} - -/* - * native_window_set_buffers_sticky_transform(..., int transform) - * All buffers queued after this call will be displayed transformed according - * to the transform parameter specified applied on top of the regular buffer - * transform. Setting this transform will disable the transform hint. - * - * Temporary - This is only intended to be used by the LEGACY camera mode, do - * not use this for anything else. - */ -static inline int native_window_set_buffers_sticky_transform( - struct ANativeWindow* window, - int transform) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM, - transform); -} - -/* - * native_window_set_buffers_timestamp(..., int64_t timestamp) - * All buffers queued after this call will be associated with the timestamp - * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO - * (the default), timestamps will be generated automatically when queueBuffer is - * called. The timestamp is measured in nanoseconds, and is normally monotonically - * increasing. The timestamp should be unaffected by time-of-day adjustments, - * and for a camera should be strictly monotonic but for a media player may be - * reset when the position is set. - */ -static inline int native_window_set_buffers_timestamp( - struct ANativeWindow* window, - int64_t timestamp) -{ - return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP, - timestamp); -} - -/* - * native_window_set_scaling_mode(..., int mode) - * All buffers queued after this call will be associated with the scaling mode - * specified. - */ -static inline int native_window_set_scaling_mode( - struct ANativeWindow* window, - int mode) -{ - return window->perform(window, NATIVE_WINDOW_SET_SCALING_MODE, - mode); -} - -/* - * native_window_api_connect(..., int api) - * connects an API to this window. only one API can be connected at a time. - * Returns -EINVAL if for some reason the window cannot be connected, which - * can happen if it's connected to some other API. - */ -static inline int native_window_api_connect( - struct ANativeWindow* window, int api) -{ - return window->perform(window, NATIVE_WINDOW_API_CONNECT, api); -} - -/* - * native_window_api_disconnect(..., int api) - * disconnect the API from this window. - * An error is returned if for instance the window wasn't connected in the - * first place. - */ -static inline int native_window_api_disconnect( - struct ANativeWindow* window, int api) -{ - return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api); -} - -/* - * native_window_dequeue_buffer_and_wait(...) - * Dequeue a buffer and wait on the fence associated with that buffer. The - * buffer may safely be accessed immediately upon this function returning. An - * error is returned if either of the dequeue or the wait operations fail. - */ -static inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw, - struct ANativeWindowBuffer** anb) { - return anw->dequeueBuffer_DEPRECATED(anw, anb); -} - -/* - * native_window_set_sideband_stream(..., native_handle_t*) - * Attach a sideband buffer stream to a native window. - */ -static inline int native_window_set_sideband_stream( - struct ANativeWindow* window, - native_handle_t* sidebandHandle) -{ - return window->perform(window, NATIVE_WINDOW_SET_SIDEBAND_STREAM, - sidebandHandle); -} - -/* - * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects) - * Set the surface damage (i.e., the region of the surface that has changed - * since the previous frame). The damage set by this call will be reset (to the - * default of full-surface damage) after calling queue, so this must be called - * prior to every frame with damage that does not cover the whole surface if the - * caller desires downstream consumers to use this optimization. - * - * The damage region is specified as an array of rectangles, with the important - * caveat that the origin of the surface is considered to be the bottom-left - * corner, as in OpenGL ES. - * - * If numRects is set to 0, rects may be NULL, and the surface damage will be - * set to the full surface (the same as if this function had not been called for - * this frame). - */ -static inline int native_window_set_surface_damage( - struct ANativeWindow* window, - const android_native_rect_t* rects, size_t numRects) -{ - return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE, - rects, numRects); -} - -/* - * native_window_set_shared_buffer_mode(..., bool sharedBufferMode) - * Enable/disable shared buffer mode - */ -static inline int native_window_set_shared_buffer_mode( - struct ANativeWindow* window, - bool sharedBufferMode) -{ - return window->perform(window, NATIVE_WINDOW_SET_SHARED_BUFFER_MODE, - sharedBufferMode); -} - -/* - * native_window_set_auto_refresh(..., autoRefresh) - * Enable/disable auto refresh when in shared buffer mode - */ -static inline int native_window_set_auto_refresh( - struct ANativeWindow* window, - bool autoRefresh) -{ - return window->perform(window, NATIVE_WINDOW_SET_AUTO_REFRESH, autoRefresh); -} - -static inline int native_window_get_refresh_cycle_duration( - struct ANativeWindow* window, - int64_t* outRefreshDuration) -{ - return window->perform(window, NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION, - outRefreshDuration); -} - -static inline int native_window_get_next_frame_id( - struct ANativeWindow* window, uint64_t* frameId) -{ - return window->perform(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID, frameId); -} - -static inline int native_window_enable_frame_timestamps( - struct ANativeWindow* window, bool enable) -{ - return window->perform(window, NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS, - enable); -} - -static inline int native_window_get_compositor_timing( - struct ANativeWindow* window, - int64_t* compositeDeadline, int64_t* compositeInterval, - int64_t* compositeToPresentLatency) -{ - return window->perform(window, NATIVE_WINDOW_GET_COMPOSITOR_TIMING, - compositeDeadline, compositeInterval, compositeToPresentLatency); -} - -static inline int native_window_get_frame_timestamps( - struct ANativeWindow* window, uint64_t frameId, - int64_t* outRequestedPresentTime, int64_t* outAcquireTime, - int64_t* outLatchTime, int64_t* outFirstRefreshStartTime, - int64_t* outLastRefreshStartTime, int64_t* outGpuCompositionDoneTime, - int64_t* outDisplayPresentTime, int64_t* outDequeueReadyTime, - int64_t* outReleaseTime) -{ - return window->perform(window, NATIVE_WINDOW_GET_FRAME_TIMESTAMPS, - frameId, outRequestedPresentTime, outAcquireTime, outLatchTime, - outFirstRefreshStartTime, outLastRefreshStartTime, - outGpuCompositionDoneTime, outDisplayPresentTime, - outDequeueReadyTime, outReleaseTime); -} - -static inline int native_window_get_wide_color_support( - struct ANativeWindow* window, bool* outSupport) { - return window->perform(window, NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT, - outSupport); -} - -static inline int native_window_get_hdr_support(struct ANativeWindow* window, - bool* outSupport) { - return window->perform(window, NATIVE_WINDOW_GET_HDR_SUPPORT, outSupport); -} - -__END_DECLS diff --git a/libsystem/include/system/window.h b/libsystem/include/system/window.h deleted file mode 100644 index efa10d647..000000000 --- a/libsystem/include/system/window.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H -#define SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H - -#include <system/window-deprecated.h> - -#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */ diff --git a/libutils/Android.bp b/libutils/Android.bp index 30e6b49a8..b7e397e43 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -18,12 +18,10 @@ cc_library_headers { host_supported: true, header_libs: [ - "liblog_headers", "libsystem_headers", "libcutils_headers" ], export_header_lib_headers: [ - "liblog_headers", "libsystem_headers", "libcutils_headers" ], diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c index 289f153e7..696e97817 100644 --- a/libvndksupport/linker.c +++ b/libvndksupport/linker.c @@ -31,7 +31,9 @@ void* android_load_sphal_library(const char* name, int flag) { }; void* handle = android_dlopen_ext(name, flag, &dlextinfo); if (!handle) { - ALOGE("Could not load %s from sphal namespace: %s.", name, dlerror()); + ALOGE( + "Could not load %s from sphal namespace: %s. ", + name, dlerror()); } return handle; } else { @@ -43,4 +45,6 @@ void* android_load_sphal_library(const char* name, int flag) { } } -int android_unload_sphal_library(void* handle) { return dlclose(handle); } +int android_unload_sphal_library(void* handle) { + return dlclose(handle); +} diff --git a/logd/tests/AndroidTest.xml b/logd/tests/AndroidTest.xml index b16bdfd3a..870461145 100644 --- a/logd/tests/AndroidTest.xml +++ b/logd/tests/AndroidTest.xml @@ -14,6 +14,7 @@ limitations under the License. --> <configuration description="Config for CTS Logging Daemon test cases"> + <option name="config-descriptor:metadata" key="component" value="systems" /> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> <option name="cleanup" value="true" /> <option name="push" value="CtsLogdTestCases->/data/local/tmp/CtsLogdTestCases" /> diff --git a/qemu_pipe/Android.bp b/qemu_pipe/Android.bp new file mode 100644 index 000000000..93c347beb --- /dev/null +++ b/qemu_pipe/Android.bp @@ -0,0 +1,14 @@ +// Copyright 2011 The Android Open Source Project + +cc_library_static { + name: "libqemu_pipe", + vendor_available: true, + sanitize: { + misc_undefined: ["integer"], + }, + srcs: ["qemu_pipe.cpp"], + local_include_dirs: ["include"], + static_libs: ["libbase"], + export_include_dirs: ["include"], + cflags: ["-Werror"], +} diff --git a/qemu_pipe/include/qemu_pipe.h b/qemu_pipe/include/qemu_pipe.h new file mode 100644 index 000000000..098749899 --- /dev/null +++ b/qemu_pipe/include/qemu_pipe.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ANDROID_CORE_INCLUDE_QEMU_PIPE_H +#define ANDROID_CORE_INCLUDE_QEMU_PIPE_H + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif +// Try to open a new Qemu fast-pipe. This function returns a file descriptor +// that can be used to communicate with a named service managed by the +// emulator. +// +// This file descriptor can be used as a standard pipe/socket descriptor. +// +// 'pipeName' is the name of the emulator service you want to connect to, +// and should begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles'). +// For backward compatibility, the 'pipe:' prefix can be omitted, and in +// that case, qemu_pipe_open will add it for you. + +// On success, return a valid file descriptor, or -1/errno on failure. E.g.: +// +// EINVAL -> unknown/unsupported pipeName +// ENOSYS -> fast pipes not available in this system. +// +// ENOSYS should never happen, except if you're trying to run within a +// misconfigured emulator. +// +// You should be able to open several pipes to the same pipe service, +// except for a few special cases (e.g. GSM modem), where EBUSY will be +// returned if more than one client tries to connect to it. +int qemu_pipe_open(const char* pipeName); + +// Send a framed message |buff| of |len| bytes through the |fd| descriptor. +// This really adds a 4-hexchar prefix describing the payload size. +// Returns 0 on success, and -1 on error. +int qemu_pipe_frame_send(int fd, const void* buff, size_t len); + +// Read a frame message from |fd|, and store it into |buff| of |len| bytes. +// If the framed message is larger than |len|, then this returns -1 and the +// content is lost. Otherwise, this returns the size of the message. NOTE: +// empty messages are possible in a framed wire protocol and do not mean +// end-of-stream. +int qemu_pipe_frame_recv(int fd, void* buff, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* ANDROID_CORE_INCLUDE_QEMU_PIPE_H */ diff --git a/qemu_pipe/qemu_pipe.cpp b/qemu_pipe/qemu_pipe.cpp new file mode 100644 index 000000000..beeccb07f --- /dev/null +++ b/qemu_pipe/qemu_pipe.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "qemu_pipe.h" + +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> + +#include <android-base/file.h> + +using android::base::ReadFully; +using android::base::WriteFully; + +// Define QEMU_PIPE_DEBUG if you want to print error messages when an error +// occurs during pipe operations. The macro should simply take a printf-style +// formatting string followed by optional arguments. +#ifndef QEMU_PIPE_DEBUG +# define QEMU_PIPE_DEBUG(...) (void)0 +#endif + +int qemu_pipe_open(const char* pipeName) { + // Sanity check. + if (!pipeName) { + errno = EINVAL; + return -1; + } + + int fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR)); + if (fd < 0) { + QEMU_PIPE_DEBUG("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, + strerror(errno)); + return -1; + } + + // Write the pipe name, *including* the trailing zero which is necessary. + size_t pipeNameLen = strlen(pipeName); + if (WriteFully(fd, pipeName, pipeNameLen + 1U)) { + return fd; + } + + // now, add 'pipe:' prefix and try again + // Note: host side will wait for the trailing '\0' to start + // service lookup. + const char pipe_prefix[] = "pipe:"; + if (WriteFully(fd, pipe_prefix, strlen(pipe_prefix)) && + WriteFully(fd, pipeName, pipeNameLen + 1U)) { + return fd; + } + QEMU_PIPE_DEBUG("%s: Could not write to %s pipe service: %s", + __FUNCTION__, pipeName, strerror(errno)); + close(fd); + return -1; +} + +int qemu_pipe_frame_send(int fd, const void* buff, size_t len) { + char header[5]; + snprintf(header, sizeof(header), "%04zx", len); + if (!WriteFully(fd, header, 4)) { + QEMU_PIPE_DEBUG("Can't write qemud frame header: %s", strerror(errno)); + return -1; + } + if (!WriteFully(fd, buff, len)) { + QEMU_PIPE_DEBUG("Can't write qemud frame payload: %s", strerror(errno)); + return -1; + } + return 0; +} + +int qemu_pipe_frame_recv(int fd, void* buff, size_t len) { + char header[5]; + if (!ReadFully(fd, header, 4)) { + QEMU_PIPE_DEBUG("Can't read qemud frame header: %s", strerror(errno)); + return -1; + } + header[4] = '\0'; + size_t size; + if (sscanf(header, "%04zx", &size) != 1) { + QEMU_PIPE_DEBUG("Malformed qemud frame header: [%.*s]", 4, header); + return -1; + } + if (size > len) { + QEMU_PIPE_DEBUG("Oversized qemud frame (% bytes, expected <= %)", size, + len); + return -1; + } + if (!ReadFully(fd, buff, size)) { + QEMU_PIPE_DEBUG("Could not read qemud frame payload: %s", + strerror(errno)); + return -1; + } + return size; +} diff --git a/rootdir/Android.mk b/rootdir/Android.mk index e199ed406..1bac36c28 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -101,6 +101,21 @@ ifneq ($(SANITIZE_ASAN_OPTIONS_FOR),) $(foreach binary, $(SANITIZE_ASAN_OPTIONS_FOR), $(eval $(call create-asan-options-module,$(binary)))) endif +# ASAN extration. +ASAN_EXTRACT_FILES := +ifeq ($(SANITIZE_TARGET_SYSTEM),true) +include $(CLEAR_VARS) +LOCAL_MODULE:= asan_extract +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_SRC_FILES := asan_extract.sh +LOCAL_INIT_RC := asan_extract.rc +# We need bzip2 on device for extraction. +LOCAL_REQUIRED_MODULES := bzip2 +include $(BUILD_PREBUILT) +ASAN_EXTRACT_FILES := asan_extract +endif + endif ####################################### @@ -114,7 +129,7 @@ LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) EXPORT_GLOBAL_ASAN_OPTIONS := ifneq ($(filter address,$(SANITIZE_TARGET)),) EXPORT_GLOBAL_ASAN_OPTIONS := export ASAN_OPTIONS include=/system/asan.options - LOCAL_REQUIRED_MODULES := asan.options $(ASAN_OPTIONS_FILES) + LOCAL_REQUIRED_MODULES := asan.options $(ASAN_OPTIONS_FILES) $(ASAN_EXTRACT_FILES) endif EXPORT_GLOBAL_GCOV_OPTIONS := diff --git a/rootdir/asan_extract.rc b/rootdir/asan_extract.rc new file mode 100644 index 000000000..4aea6a374 --- /dev/null +++ b/rootdir/asan_extract.rc @@ -0,0 +1,3 @@ +# When /data is available, look for /system/asan.tar.gz and potentially extract. +on post-fs-data + exec - system system -- /system/bin/asan_extract diff --git a/rootdir/asan_extract.sh b/rootdir/asan_extract.sh new file mode 100644 index 000000000..2d723207b --- /dev/null +++ b/rootdir/asan_extract.sh @@ -0,0 +1,95 @@ +#!/system/bin/sh + +# +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This script will extract ASAN libraries from /system/asan.tar.gz to /data and then reboot. + +# TODO: +# * Timestamp or something to know when to run this again. Right now take the existence of +# /data/lib as we're already done. +# * Need to distinguish pre- from post-decryption for FDE. + +SRC=/system/asan.tar.bz2 +MD5_FILE=/data/asan.md5sum +ASAN_DIR=/data/asan +# Minimum /data size in blocks. Arbitrarily 512M. +MIN_DATA_SIZE=131072 + +# Checks for FDE pre-decrypt state. + +VOLD_STATUS=$(getprop vold.decrypt) +if [ "$VOLD_STATUS" = "trigger_restart_min_framework" ] ; then + log -p i -t asan_install "Pre-decrypt FDE detected (by vold property)!" + exit 1 +fi + +STATFS_BLOCKS=$(stat -f -c '%b' /data) +if [ "$STATFS_BLOCKS" -le "$MIN_DATA_SIZE" ] ; then + log -p i -t asan_install "Pre-decrypt FDE detected (by /data size)!" + exit 1 +fi + +# Check for ASAN source. + +if ! test -f $SRC ; then + log -p i -t asan_install "Did not find $SRC!" + exit 1 +fi + +log -p i -t asan_install "Found $SRC, checking whether we need to apply it." + +# Checksum check. + +ASAN_TAR_MD5=$(md5sum $SRC) +if test -f $MD5_FILE ; then + INSTALLED_MD5=$(cat $MD5_FILE) + if [ "x$ASAN_TAR_MD5" = "x$INSTALLED_MD5" ] ; then + log -p i -t asan_install "Checksums match, nothing to be done here." + exit 0 + fi +fi + +# Actually apply the source. + +# Just clean up, helps with restorecon. +rm -rf $ASAN_DIR + +log -p i -t asan_install "Untarring $SRC..." + +# Unzip from /system/asan.tar.gz into data. Need to pipe as gunzip is not on device. +bzip2 -c -d $SRC | tar -x -f - --no-same-owner -C / || exit 1 + +# Cannot log here, log would run with system_data_file. + +# Set correct permission bits. +chmod -R 744 $ASAN_DIR +cd $ASAN_DIR ; find . -type d -exec chmod 755 {} \; + +restorecon -R -F $ASAN_DIR/*/lib* + +log -p i -t asan_install "Fixed selinux labels..." + + +# Now write down our checksum to mark the extraction complete. +echo "$ASAN_TAR_MD5" > $MD5_FILE + +# We want to reboot now. It seems it is not possible to run "reboot" here, the device will +# just be stuck. + +log -p i -t asan_install "Signaling init to reboot..." + +setprop sys.powerctl reboot diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 436589ec5..56066bcf2 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -7,6 +7,10 @@ dir.system = /system/bin/ dir.system = /system/xbin/ dir.vendor = /vendor/bin/ +dir.test = /data/nativetest/ +dir.test = /data/nativetest64/ +dir.test = /data/benchmarktest/ +dir.test = /data/benchmarktest64/ [system] additional.namespaces = sphal,vndk,rs @@ -84,7 +88,7 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libui.so:libvndksupport.so +namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so ############################################################################### @@ -105,9 +109,23 @@ namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} namespace.vndk.links = default namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so - +############################################################################### +# Namespace config for vendor processes. In O, no restriction is enforced for +# them. However, in O-MR1, access to /system/${LIB} will not be allowed to +# the default namespace. 'system' namespace will be added to give limited +# (LL-NDK only) access. +############################################################################### [vendor] namespace.default.isolated = false namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} + +############################################################################### +# Namespace config for tests. No VNDK restriction is enforced for these tests. +############################################################################### +[test] +namespace.default.isolated = false +namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} + +namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} diff --git a/rootdir/init.rc b/rootdir/init.rc index d503ffe4f..917e99db6 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -61,18 +61,22 @@ on init mkdir /dev/stune/foreground mkdir /dev/stune/background mkdir /dev/stune/top-app + mkdir /dev/stune/rt chown system system /dev/stune chown system system /dev/stune/foreground chown system system /dev/stune/background chown system system /dev/stune/top-app + chown system system /dev/stune/rt chown system system /dev/stune/tasks chown system system /dev/stune/foreground/tasks chown system system /dev/stune/background/tasks chown system system /dev/stune/top-app/tasks + chown system system /dev/stune/rt/tasks chmod 0664 /dev/stune/tasks chmod 0664 /dev/stune/foreground/tasks chmod 0664 /dev/stune/background/tasks chmod 0664 /dev/stune/top-app/tasks + chmod 0664 /dev/stune/rt/tasks # Mount staging areas for devices managed by vold # See storage config details at http://source.android.com/tech/storage/ diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp index 3b6867cf1..6b9d72359 100644 --- a/trusty/keymaster/Android.bp +++ b/trusty/keymaster/Android.bp @@ -33,7 +33,8 @@ cc_binary { shared_libs: [ "libcrypto", "libcutils", - "libkeymaster1", + "libkeymaster_portable", + "libkeymaster_staging", "libtrusty", "libkeymaster_messages", "libsoftkeymasterdevice", |