diff options
-rw-r--r-- | cmds/installd/commands.cpp | 246 | ||||
-rw-r--r-- | cmds/installd/commands.h | 37 | ||||
-rw-r--r-- | cmds/installd/installd.cpp | 113 | ||||
-rw-r--r-- | cmds/installd/installd_constants.h | 5 | ||||
-rw-r--r-- | include/media/hardware/CryptoAPI.h | 17 | ||||
-rw-r--r-- | include/ui/FramebufferNativeWindow.h | 102 | ||||
-rw-r--r-- | include/ui/Rect.h | 13 | ||||
-rw-r--r-- | libs/gui/tests/StreamSplitter_test.cpp | 57 | ||||
-rw-r--r-- | libs/ui/Android.mk | 1 | ||||
-rw-r--r-- | libs/ui/FramebufferNativeWindow.cpp | 372 |
10 files changed, 185 insertions, 778 deletions
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index 7544e4dff1..6b004290cc 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -51,109 +51,73 @@ namespace installd { static const char* kCpPath = "/system/bin/cp"; -int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) { - if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { - ALOGE("invalid uid/gid: %d %d\n", uid, gid); - return -1; - } - - return make_user_data(uuid, pkgname, uid, 0, seinfo); -} - -int uninstall(const char *uuid, const char *pkgname, userid_t userid) { - std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname)); - std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname)); - - int res = 0; - res |= delete_dir_contents_and_dir(ce_package_path); - // TODO: include result once 25796509 is fixed - delete_dir_contents_and_dir(de_package_path); - return res; -} - -int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid) -{ - struct stat s; - - if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { - ALOGE("invalid uid/gid: %d %d\n", uid, gid); - return -1; - } - - // TODO: handle user_de paths - std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname)); - const char* pkgdir = _pkgdir.c_str(); - - if (stat(pkgdir, &s) < 0) return -1; - - if (s.st_uid != 0 || s.st_gid != 0) { - ALOGE("fixing uid of non-root pkg: %s %" PRIu32 " %" PRIu32 "\n", pkgdir, s.st_uid, s.st_gid); - return -1; - } - - if (chmod(pkgdir, 0751) < 0) { - ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno)); - unlink(pkgdir); - return -errno; +int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags, + appid_t appid, const char* seinfo) { + uid_t uid = multiuser_get_uid(userid, appid); + if (flags & FLAG_CE_STORAGE) { + auto path = create_data_user_package_path(uuid, userid, pkgname); + if (fs_prepare_dir_strict(path.c_str(), 0751, uid, uid) != 0) { + PLOG(ERROR) << "Failed to prepare " << path; + return -1; + } + if (selinux_android_setfilecon(path.c_str(), pkgname, seinfo, uid) < 0) { + PLOG(ERROR) << "Failed to setfilecon " << path; + return -1; + } } - if (chown(pkgdir, uid, gid) < 0) { - ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); - unlink(pkgdir); - return -errno; + if (flags & FLAG_DE_STORAGE) { + auto path = create_data_user_de_package_path(uuid, userid, pkgname); + if (fs_prepare_dir_strict(path.c_str(), 0751, uid, uid) == -1) { + PLOG(ERROR) << "Failed to prepare " << path; + return -1; + } + if (selinux_android_setfilecon(path.c_str(), pkgname, seinfo, uid) < 0) { + PLOG(ERROR) << "Failed to setfilecon " << path; + return -1; + } } - return 0; } -int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) { - std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname)); - std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname)); +int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) { + std::string suffix = ""; + if (flags & FLAG_CLEAR_CACHE_ONLY) { + suffix = CACHE_DIR_POSTFIX; + } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) { + suffix = CODE_CACHE_DIR_POSTFIX; + } int res = 0; - res |= delete_dir_contents(ce_package_path); - // TODO: include result once 25796509 is fixed - delete_dir_contents(de_package_path); - return res; -} - -int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, - const char* seinfo) { - std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname)); - std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname)); - - const char* c_ce_package_path = ce_package_path.c_str(); - const char* c_de_package_path = de_package_path.c_str(); - - if (fs_prepare_dir(c_ce_package_path, 0751, uid, uid) == -1) { - PLOG(ERROR) << "Failed to prepare " << ce_package_path; - unlink(c_ce_package_path); - return -1; + if (flags & FLAG_CE_STORAGE) { + auto path = create_data_user_package_path(uuid, userid, pkgname) + suffix; + if (access(path.c_str(), F_OK) == 0) { + res |= delete_dir_contents(path); + } } - if (selinux_android_setfilecon(c_ce_package_path, pkgname, seinfo, uid) < 0) { - PLOG(ERROR) << "Failed to setfilecon " << ce_package_path; - unlink(c_ce_package_path); - return -1; + if (flags & FLAG_DE_STORAGE) { + auto path = create_data_user_de_package_path(uuid, userid, pkgname) + suffix; + if (access(path.c_str(), F_OK) == 0) { + res |= delete_dir_contents(path); + } } + return res; +} - if (fs_prepare_dir(c_de_package_path, 0751, uid, uid) == -1) { - PLOG(ERROR) << "Failed to prepare " << de_package_path; - unlink(c_de_package_path); - // TODO: include result once 25796509 is fixed - return 0; +int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) { + int res = 0; + if (flags & FLAG_CE_STORAGE) { + res |= delete_dir_contents_and_dir( + create_data_user_package_path(uuid, userid, pkgname)); } - if (selinux_android_setfilecon(c_de_package_path, pkgname, seinfo, uid) < 0) { - PLOG(ERROR) << "Failed to setfilecon " << de_package_path; - unlink(c_de_package_path); - // TODO: include result once 25796509 is fixed - return 0; + if (flags & FLAG_DE_STORAGE) { + res |= delete_dir_contents_and_dir( + create_data_user_de_package_path(uuid, userid, pkgname)); } - - return 0; + return res; } -int copy_complete_app(const char *from_uuid, const char *to_uuid, - const char *package_name, const char *data_app_name, appid_t appid, - const char* seinfo) { +int move_complete_app(const char *from_uuid, const char *to_uuid, const char *package_name, + const char *data_app_name, appid_t appid, const char* seinfo) { std::vector<userid_t> users = get_known_users(from_uuid); // Copy app @@ -207,8 +171,8 @@ int copy_complete_app(const char *from_uuid, const char *to_uuid, goto fail; } - uid_t uid = multiuser_get_uid(user, appid); - if (make_user_data(to_uuid, package_name, uid, user, seinfo) != 0) { + if (create_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE, + appid, seinfo) != 0) { LOG(ERROR) << "Failed to create package target " << to; goto fail; } @@ -232,11 +196,12 @@ int copy_complete_app(const char *from_uuid, const char *to_uuid, << ": status " << rc; goto fail; } - } - if (restorecon_data(to_uuid, package_name, seinfo, multiuser_get_uid(0, appid)) != 0) { - LOG(ERROR) << "Failed to restorecon"; - goto fail; + if (restorecon_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE, + appid, seinfo) != 0) { + LOG(ERROR) << "Failed to restorecon"; + goto fail; + } } // We let the framework scan the new location and persist that before @@ -293,33 +258,6 @@ int delete_user(const char *uuid, userid_t userid) { return res; } -int delete_cache(const char *uuid, const char *pkgname, userid_t userid) -{ - std::string _cachedir( - create_data_user_package_path(uuid, userid, pkgname) + CACHE_DIR_POSTFIX); - const char* cachedir = _cachedir.c_str(); - - /* delete contents, not the directory, no exceptions */ - return delete_dir_contents(cachedir, 0, NULL); -} - -int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid) -{ - std::string _codecachedir( - create_data_user_package_path(uuid, userid, pkgname) + CODE_CACHE_DIR_POSTFIX); - const char* codecachedir = _codecachedir.c_str(); - - struct stat s; - - /* it's okay if code cache is missing */ - if (lstat(codecachedir, &s) == -1 && errno == ENOENT) { - return 0; - } - - /* delete contents, not the directory, no exceptions */ - return delete_dir_contents(codecachedir, 0, NULL); -} - /* Try to ensure free_size bytes of storage are available. * Returns 0 on success. * This is rather simple-minded because doing a full LRU would @@ -413,32 +351,6 @@ int free_cache(const char *uuid, int64_t free_size) return data_disk_free(data_path) >= free_size ? 0 : -1; } -int move_dex(const char *src, const char *dst, const char *instruction_set) -{ - char src_dex[PKG_PATH_MAX]; - char dst_dex[PKG_PATH_MAX]; - - if (validate_apk_path(src)) { - ALOGE("invalid apk path '%s' (bad prefix)\n", src); - return -1; - } - if (validate_apk_path(dst)) { - ALOGE("invalid apk path '%s' (bad prefix)\n", dst); - return -1; - } - - if (!create_cache_path(src_dex, src, instruction_set)) return -1; - if (!create_cache_path(dst_dex, dst, instruction_set)) return -1; - - ALOGV("move %s -> %s\n", src_dex, dst_dex); - if (rename(src_dex, dst_dex) < 0) { - ALOGE("Couldn't move %s: %s\n", src_dex, strerror(errno)); - return -1; - } else { - return 0; - } -} - int rm_dex(const char *path, const char *instruction_set) { char dex_path[PKG_PATH_MAX]; @@ -461,11 +373,10 @@ int rm_dex(const char *path, const char *instruction_set) } } -int get_size(const char *uuid, const char *pkgname, int userid, const char *apkpath, - const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, - const char *instruction_set, int64_t *_codesize, int64_t *_datasize, - int64_t *_cachesize, int64_t* _asecsize) -{ +int get_app_size(const char *uuid, const char *pkgname, int userid, int flags, + const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, + const char *asecpath, const char *instruction_set, int64_t *_codesize, int64_t *_datasize, + int64_t *_cachesize, int64_t* _asecsize) { DIR *d; int dfd; struct dirent *de; @@ -534,6 +445,8 @@ int get_size(const char *uuid, const char *pkgname, int userid, const char *apkp for (auto user : users) { // TODO: handle user_de directories + if (!(flags & FLAG_CE_STORAGE)) continue; + std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname)); const char* pkgdir = _pkgdir.c_str(); @@ -1571,31 +1484,30 @@ fail: return -1; } -int restorecon_data(const char* uuid, const char* pkgName, const char* seinfo, appid_t appid) { +int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags, + appid_t appid, const char* seinfo) { int res = 0; // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here. - unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE; + unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE; if (!pkgName || !seinfo) { ALOGE("Package name or seinfo tag is null when trying to restorecon."); return -1; } - // Relabel package directory for all users - std::vector<userid_t> users = get_known_users(uuid); - for (auto user : users) { - uid_t uid = multiuser_get_uid(user, appid); - - std::string ce_package_path(create_data_user_package_path(uuid, user, pkgName)); - std::string de_package_path(create_data_user_de_package_path(uuid, user, pkgName)); - - if (selinux_android_restorecon_pkgdir(ce_package_path.c_str(), seinfo, uid, flags) < 0) { - PLOG(ERROR) << "restorecon failed for " << ce_package_path; + uid_t uid = multiuser_get_uid(userid, appid); + if (flags & FLAG_CE_STORAGE) { + auto path = create_data_user_package_path(uuid, userid, pkgName); + if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) { + PLOG(ERROR) << "restorecon failed for " << path; res = -1; } - if (selinux_android_restorecon_pkgdir(de_package_path.c_str(), seinfo, uid, flags) < 0) { - PLOG(ERROR) << "restorecon failed for " << de_package_path; + } + if (flags & FLAG_DE_STORAGE) { + auto path = create_data_user_de_package_path(uuid, userid, pkgName); + if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) { + PLOG(ERROR) << "restorecon failed for " << path; // TODO: include result once 25796509 is fixed } } diff --git a/cmds/installd/commands.h b/cmds/installd/commands.h index 55a6e62e70..5510e7be67 100644 --- a/cmds/installd/commands.h +++ b/cmds/installd/commands.h @@ -28,28 +28,24 @@ namespace android { namespace installd { -int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo); -int uninstall(const char *uuid, const char *pkgname, userid_t userid); -int renamepkg(const char *oldpkgname, const char *newpkgname); -int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); -int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); -int make_user_data(const char *uuid, const char *pkgname, uid_t uid, - userid_t userid, const char* seinfo); -int copy_complete_app(const char* from_uuid, const char *to_uuid, - const char *package_name, const char *data_app_name, appid_t appid, - const char* seinfo); +int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags, + appid_t appid, const char* seinfo); +int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags, + appid_t appid, const char* seinfo); +int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags); +int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags); + +int move_complete_app(const char* from_uuid, const char *to_uuid, const char *package_name, + const char *data_app_name, appid_t appid, const char* seinfo); + +int get_app_size(const char *uuid, const char *pkgname, int userid, int flags, + const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, + const char *asecpath, const char *instruction_set, int64_t *codesize, int64_t *datasize, + int64_t *cachesize, int64_t *asecsize); + int make_user_config(userid_t userid); int delete_user(const char *uuid, userid_t userid); -int delete_cache(const char *uuid, const char *pkgname, userid_t userid); -int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid); -int move_dex(const char *src, const char *dst, const char *instruction_set); int rm_dex(const char *path, const char *instruction_set); -int protect(char *pkgname, gid_t gid); -int get_size(const char *uuid, const char *pkgname, int userid, - const char *apkpath, const char *libdirpath, - const char *fwdlock_apkpath, const char *asecpath, - const char *instruction_set, int64_t *codesize, int64_t *datasize, - int64_t *cachesize, int64_t *asecsize); int free_cache(const char *uuid, int64_t free_size); int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set, int dexopt_needed, const char* oat_dir, int dexopt_flags); @@ -57,11 +53,8 @@ int mark_boot_complete(const char *instruction_set); int movefiles(); int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId); int idmap(const char *target_path, const char *overlay_path, uid_t uid); -int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid); int create_oat_dir(const char* oat_dir, const char *instruction_set); int rm_package_dir(const char* apk_path); -int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, - const char *instruction_set); int link_file(const char *relative_path, const char *from_base, const char *to_base); } // namespace installd diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index 17ae521d8a..8542c4ab0b 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -18,6 +18,7 @@ #include <selinux/android.h> #include <selinux/avc.h> #include <sys/capability.h> +#include <sys/fsuid.h> #include <sys/prctl.h> #include <sys/socket.h> #include <sys/stat.h> @@ -44,6 +45,7 @@ #define TOKEN_MAX 16 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ +#define DEBUG_FBE 0 namespace android { namespace installd { @@ -188,9 +190,26 @@ static int do_ping(char **arg ATTRIBUTE_UNUSED, char reply[REPLY_MAX] ATTRIBUTE_ return 0; } -static int do_install(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return install(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); /* uuid, pkgname, uid, gid, seinfo */ +static int do_create_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char *uuid, const char *pkgname, userid_t userid, int flags, + appid_t appid, const char* seinfo */ + return create_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); +} + +static int do_restorecon_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char* uuid, const char* pkgName, userid_t userid, int flags, + appid_t appid, const char* seinfo */ + return restorecon_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); +} + +static int do_clear_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char *uuid, const char *pkgname, userid_t userid, int flags */ + return clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); +} + +static int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char *uuid, const char *pkgname, userid_t userid, int flags */ + return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); } static int do_dexopt(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) @@ -205,52 +224,28 @@ static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNU return mark_boot_complete(arg[0] /* instruction set */); } -static int do_move_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return move_dex(arg[0], arg[1], arg[2]); /* src, dst, instruction_set */ -} - static int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */ } -static int do_remove(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return uninstall(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ -} - -static int do_fixuid(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return fix_uid(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); /* uuid, pkgname, uid, gid */ -} - static int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */ { return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */ } -static int do_rm_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return delete_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ -} - -static int do_rm_code_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return delete_code_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ -} - -static int do_get_size(char **arg, char reply[REPLY_MAX]) -{ +static int do_get_app_size(char **arg, char reply[REPLY_MAX]) { int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; int64_t asecsize = 0; int res = 0; - /* uuid, pkgdir, userid, apkpath */ - res = get_size(parse_null(arg[0]), arg[1], atoi(arg[2]), arg[3], arg[4], arg[5], arg[6], - arg[7], &codesize, &datasize, &cachesize, &asecsize); + /* const char *uuid, const char *pkgname, userid_t userid, int flags, + const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, + const char *asecpath, const char *instruction_set */ + res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4], arg[5], + arg[6], arg[7], arg[8], &codesize, &datasize, &cachesize, &asecsize); /* * Each int64_t can take up 22 characters printed out. Make sure it @@ -261,21 +256,10 @@ static int do_get_size(char **arg, char reply[REPLY_MAX]) return res; } -static int do_rm_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ -} - -static int do_cp_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - // from_uuid, to_uuid, package_name, data_app_name, appid, seinfo - return copy_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]); -} - -static int do_mk_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); - /* uuid, pkgname, uid, userid, seinfo */ +static int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char* from_uuid, const char *to_uuid, const char *package_name, + const char *data_app_name, appid_t appid, const char* seinfo */ + return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]); } static int do_mk_user_config(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) @@ -303,12 +287,6 @@ static int do_idmap(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) return idmap(arg[0], arg[1], atoi(arg[2])); } -static int do_restorecon_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) -{ - return restorecon_data(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3])); - /* uuid, pkgName, seinfo, uid*/ -} - static int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { /* oat_dir, instruction_set */ @@ -335,29 +313,26 @@ struct cmdinfo { struct cmdinfo cmds[] = { { "ping", 0, do_ping }, - { "install", 5, do_install }, + + { "create_app_data", 6, do_create_app_data }, + { "restorecon_app_data", 6, do_restorecon_app_data }, + { "clear_app_data", 4, do_clear_app_data }, + { "destroy_app_data", 4, do_destroy_app_data }, + { "move_complete_app", 6, do_move_complete_app }, + { "get_app_size", 9, do_get_app_size }, + { "dexopt", 7, do_dexopt }, { "markbootcomplete", 1, do_mark_boot_complete }, - { "movedex", 3, do_move_dex }, { "rmdex", 2, do_rm_dex }, - { "remove", 3, do_remove }, - { "fixuid", 4, do_fixuid }, { "freecache", 2, do_free_cache }, - { "rmcache", 3, do_rm_cache }, - { "rmcodecache", 3, do_rm_code_cache }, - { "getsize", 8, do_get_size }, - { "rmuserdata", 3, do_rm_user_data }, - { "cpcompleteapp", 6, do_cp_complete_app }, { "movefiles", 0, do_movefiles }, { "linklib", 4, do_linklib }, - { "mkuserdata", 5, do_mk_user_data }, { "mkuserconfig", 1, do_mk_user_config }, { "rmuser", 2, do_rm_user }, { "idmap", 3, do_idmap }, - { "restorecondata", 4, do_restorecon_data }, { "createoatdir", 2, do_create_oat_dir }, { "rmpackagedir", 1, do_rm_package_dir }, - { "linkfile", 3, do_link_file } + { "linkfile", 3, do_link_file }, }; static int readx(int s, void *_buf, int count) @@ -773,6 +748,12 @@ static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { } fcntl(lsocket, F_SETFD, FD_CLOEXEC); + // Perform all filesystem access as system so that FBE emulation mode + // can block access using chmod 000. +#if DEBUG_FBE + setfsuid(AID_SYSTEM); +#endif + for (;;) { alen = sizeof(addr); s = accept(lsocket, &addr, &alen); diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h index 058db4c85c..220de9af65 100644 --- a/cmds/installd/installd_constants.h +++ b/cmds/installd/installd_constants.h @@ -57,6 +57,11 @@ constexpr const char* IDMAP_SUFFIX = "@idmap"; constexpr size_t PKG_NAME_MAX = 128u; /* largest allowed package name */ constexpr size_t PKG_PATH_MAX = 256u; /* max size of any path we use */ +constexpr int FLAG_DE_STORAGE = 1 << 0; +constexpr int FLAG_CE_STORAGE = 1 << 1; +constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 2; +constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 3; + /* dexopt needed flags matching those in dalvik.system.DexFile */ constexpr int DEXOPT_DEX2OAT_NEEDED = 1; constexpr int DEXOPT_PATCHOAT_NEEDED = 2; diff --git a/include/media/hardware/CryptoAPI.h b/include/media/hardware/CryptoAPI.h index 3e3257f956..0e86aacc6f 100644 --- a/include/media/hardware/CryptoAPI.h +++ b/include/media/hardware/CryptoAPI.h @@ -46,10 +46,8 @@ struct CryptoPlugin { enum Mode { kMode_Unencrypted = 0, kMode_AES_CTR = 1, - - // Neither key nor iv are being used in this mode. - // Each subsample is encrypted w/ an iv of all zeroes. - kMode_AES_WV = 2, // FIX constant + kMode_AES_WV = 2, + kMode_AES_CBC = 3, }; struct SubSample { @@ -57,6 +55,16 @@ struct CryptoPlugin { uint32_t mNumBytesOfEncryptedData; }; + struct Pattern { + // Number of blocks to be encrypted in the pattern. If zero, pattern + // encryption is inoperative. + uint32_t mEncryptBlocks; + + // Number of blocks to be skipped (left clear) in the pattern. If zero, + // pattern encryption is inoperative. + uint32_t mSkipBlocks; + }; + CryptoPlugin() {} virtual ~CryptoPlugin() {} @@ -96,6 +104,7 @@ struct CryptoPlugin { const uint8_t key[16], const uint8_t iv[16], Mode mode, + const Pattern &pattern, const void *srcPtr, const SubSample *subSamples, size_t numSubSamples, void *dstPtr, diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h deleted file mode 100644 index 6b66d5f66b..0000000000 --- a/include/ui/FramebufferNativeWindow.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007 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 INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP -#warning "FramebufferNativeWindow is deprecated" -#endif - -#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H -#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> - -#include <utils/threads.h> -#include <utils/String8.h> - -#include <ui/ANativeObjectBase.h> -#include <ui/Rect.h> - -#define MIN_NUM_FRAME_BUFFERS 2 -#define MAX_NUM_FRAME_BUFFERS 3 - -extern "C" EGLNativeWindowType android_createDisplaySurface(void); - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Surface; -class NativeBuffer; - -// --------------------------------------------------------------------------- - -class FramebufferNativeWindow - : public ANativeObjectBase< - ANativeWindow, - FramebufferNativeWindow, - LightRefBase<FramebufferNativeWindow> > -{ -public: - FramebufferNativeWindow(); - - framebuffer_device_t const * getDevice() const { return fbDev; } - - bool isUpdateOnDemand() const { return mUpdateOnDemand; } - status_t setUpdateRectangle(const Rect& updateRect); - status_t compositionComplete(); - - void dump(String8& result); - - // for debugging only - int getCurrentBufferIndex() const; - -private: - friend class LightRefBase<FramebufferNativeWindow>; - ~FramebufferNativeWindow(); // this class cannot be overloaded - static int setSwapInterval(ANativeWindow* window, int interval); - static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd); - static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd); - static int query(const ANativeWindow* window, int what, int* value); - static int perform(ANativeWindow* window, int operation, ...); - - static int dequeueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer** buffer); - static int queueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int lockBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer); - - framebuffer_device_t* fbDev; - alloc_device_t* grDev; - - sp<NativeBuffer> buffers[MAX_NUM_FRAME_BUFFERS]; - sp<NativeBuffer> front; - - mutable Mutex mutex; - Condition mCondition; - int32_t mNumBuffers; - int32_t mNumFreeBuffers; - int32_t mBufferHead; - int32_t mCurrentBufferIndex; - bool mUpdateOnDemand; -}; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H - diff --git a/include/ui/Rect.h b/include/ui/Rect.h index 6310502b34..a8513a9004 100644 --- a/include/ui/Rect.h +++ b/include/ui/Rect.h @@ -39,13 +39,8 @@ public: inline Rect() : Rect(INVALID_RECT) {} - inline Rect(int32_t w, int32_t h) { - left = top = 0; - right = w; - bottom = h; - } - - inline Rect(uint32_t w, uint32_t h) { + template <typename T> + inline Rect(T w, T h) { if (w > INT32_MAX) { ALOG(LOG_WARN, "Rect", "Width %u too large for Rect class, clamping", w); @@ -57,8 +52,8 @@ public: h = INT32_MAX; } left = top = 0; - right = w; - bottom = h; + right = static_cast<int32_t>(w); + bottom = static_cast<int32_t>(h); } inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) { diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index c7ce263e5a..498492e179 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -52,42 +52,16 @@ struct DummyListener : public BnConsumerListener { virtual void onSidebandStreamChanged() {} }; -class CountedAllocator : public BnGraphicBufferAlloc { -public: - CountedAllocator() : mAllocCount(0) { - sp<ISurfaceComposer> composer(ComposerService::getComposerService()); - mAllocator = composer->createGraphicBufferAlloc(); - } - - virtual ~CountedAllocator() {} - - virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error) { - ++mAllocCount; - sp<GraphicBuffer> buffer = mAllocator->createGraphicBuffer(w, h, format, - usage, error); - return buffer; - } - - int getAllocCount() const { return mAllocCount; } - -private: - sp<IGraphicBufferAlloc> mAllocator; - int mAllocCount; -}; - static const uint32_t TEST_DATA = 0x12345678u; TEST_F(StreamSplitterTest, OneInputOneOutput) { - sp<CountedAllocator> allocator(new CountedAllocator); - sp<IGraphicBufferProducer> inputProducer; sp<IGraphicBufferConsumer> inputConsumer; - BufferQueue::createBufferQueue(&inputProducer, &inputConsumer, allocator); + BufferQueue::createBufferQueue(&inputProducer, &inputConsumer); sp<IGraphicBufferProducer> outputProducer; sp<IGraphicBufferConsumer> outputConsumer; - BufferQueue::createBufferQueue(&outputProducer, &outputConsumer, allocator); + BufferQueue::createBufferQueue(&outputProducer, &outputConsumer); ASSERT_EQ(OK, outputConsumer->consumerConnect(new DummyListener, false)); sp<StreamSplitter> splitter; @@ -95,6 +69,9 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { ASSERT_EQ(OK, status); ASSERT_EQ(OK, splitter->addOutput(outputProducer)); + // Never allow the output BufferQueue to allocate a buffer + ASSERT_EQ(OK, outputProducer->allowAllocation(false)); + IGraphicBufferProducer::QueueBufferOutput qbOutput; ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput)); @@ -118,6 +95,10 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); + // Now that we have dequeued/allocated one buffer, prevent any further + // allocations + ASSERT_EQ(OK, inputProducer->allowAllocation(false)); + BufferItem item; ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0)); @@ -130,26 +111,25 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); + // This should succeed even with allocation disabled since it will have + // received the buffer back from the output BufferQueue ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); - - ASSERT_EQ(1, allocator->getAllocCount()); } TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { const int NUM_OUTPUTS = 4; - sp<CountedAllocator> allocator(new CountedAllocator); sp<IGraphicBufferProducer> inputProducer; sp<IGraphicBufferConsumer> inputConsumer; - BufferQueue::createBufferQueue(&inputProducer, &inputConsumer, allocator); + BufferQueue::createBufferQueue(&inputProducer, &inputConsumer); sp<IGraphicBufferProducer> outputProducers[NUM_OUTPUTS] = {}; sp<IGraphicBufferConsumer> outputConsumers[NUM_OUTPUTS] = {}; for (int output = 0; output < NUM_OUTPUTS; ++output) { BufferQueue::createBufferQueue(&outputProducers[output], - &outputConsumers[output], allocator); + &outputConsumers[output]); ASSERT_EQ(OK, outputConsumers[output]->consumerConnect( new DummyListener, false)); } @@ -159,6 +139,9 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { ASSERT_EQ(OK, status); for (int output = 0; output < NUM_OUTPUTS; ++output) { ASSERT_EQ(OK, splitter->addOutput(outputProducers[output])); + + // Never allow the output BufferQueues to allocate a buffer + ASSERT_EQ(OK, outputProducers[output]->allowAllocation(false)); } IGraphicBufferProducer::QueueBufferOutput qbOutput; @@ -184,6 +167,10 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); + // Now that we have dequeued/allocated one buffer, prevent any further + // allocations + ASSERT_EQ(OK, inputProducer->allowAllocation(false)); + for (int output = 0; output < NUM_OUTPUTS; ++output) { BufferItem item; ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0)); @@ -199,11 +186,11 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { Fence::NO_FENCE)); } + // This should succeed even with allocation disabled since it will have + // received the buffer back from the output BufferQueues ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, inputProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); - - ASSERT_EQ(1, allocator->getAllocCount()); } TEST_F(StreamSplitterTest, OutputAbandonment) { diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 54ff741a4e..e4cdcab04a 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -36,7 +36,6 @@ LOCAL_CPPFLAGS += -Wno-padded LOCAL_SRC_FILES := \ Fence.cpp \ - FramebufferNativeWindow.cpp \ FrameStats.cpp \ GraphicBuffer.cpp \ GraphicBufferAllocator.cpp \ diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp deleted file mode 100644 index 59db157506..0000000000 --- a/libs/ui/FramebufferNativeWindow.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* -** -** Copyright 2007 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. -*/ - -#define LOG_TAG "FramebufferNativeWindow" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include <cutils/log.h> -#include <cutils/atomic.h> -#include <utils/threads.h> -#include <utils/RefBase.h> - -#include <ui/ANativeObjectBase.h> -#include <ui/Fence.h> -#define INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP -#include <ui/FramebufferNativeWindow.h> -#undef INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP -#include <ui/Rect.h> - -#include <EGL/egl.h> - -#include <hardware/hardware.h> -#include <hardware/gralloc.h> - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -class NativeBuffer final - : public ANativeObjectBase< - ANativeWindowBuffer, - NativeBuffer, - LightRefBase<NativeBuffer>> -{ -public: - NativeBuffer(int w, int h, int f, int u) : BASE() { - ANativeWindowBuffer::width = w; - ANativeWindowBuffer::height = h; - ANativeWindowBuffer::format = f; - ANativeWindowBuffer::usage = u; - } -private: - friend class LightRefBase<NativeBuffer>; -}; - - -/* - * This implements the (main) framebuffer management. This class is used - * mostly by SurfaceFlinger, but also by command line GL application. - * - * In fact this is an implementation of ANativeWindow on top of - * the framebuffer. - * - * Currently it is pretty simple, it manages only two buffers (the front and - * back buffer). - * - */ - -FramebufferNativeWindow::FramebufferNativeWindow() - : BASE(), fbDev(0), grDev(0), mCurrentBufferIndex(0), mUpdateOnDemand(false) -{ - hw_module_t const* module; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { - int err; - int i; - err = framebuffer_open(module, &fbDev); - ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); - - err = gralloc_open(module, &grDev); - ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err)); - - // bail out if we can't initialize the modules - if (!fbDev || !grDev) - return; - - mUpdateOnDemand = (fbDev->setUpdateRect != 0); - - // initialize the buffer FIFO - if(fbDev->numFramebuffers >= MIN_NUM_FRAME_BUFFERS && - fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){ - mNumBuffers = fbDev->numFramebuffers; - } else { - mNumBuffers = MIN_NUM_FRAME_BUFFERS; - } - mNumFreeBuffers = mNumBuffers; - mBufferHead = mNumBuffers-1; - - /* - * This does not actually change the framebuffer format. It merely - * fakes this format to surfaceflinger so that when it creates - * framebuffer surfaces it will use this format. It's really a giant - * HACK to allow interworking with buggy gralloc+GPU driver - * implementations. You should *NEVER* need to set this for shipping - * devices. - */ -#ifdef FRAMEBUFFER_FORCE_FORMAT - *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT; -#endif - - for (i = 0; i < mNumBuffers; i++) { - buffers[i] = new NativeBuffer( - static_cast<int>(fbDev->width), - static_cast<int>(fbDev->height), - fbDev->format, GRALLOC_USAGE_HW_FB); - } - - for (i = 0; i < mNumBuffers; i++) { - err = grDev->alloc(grDev, - static_cast<int>(fbDev->width), - static_cast<int>(fbDev->height), - fbDev->format, GRALLOC_USAGE_HW_FB, - &buffers[i]->handle, &buffers[i]->stride); - - ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s", - i, fbDev->width, fbDev->height, strerror(-err)); - - if (err) { - mNumBuffers = i; - mNumFreeBuffers = i; - mBufferHead = mNumBuffers-1; - break; - } - } - - const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; - const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; - const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; - const_cast<int&>(ANativeWindow::minSwapInterval) = - fbDev->minSwapInterval; - const_cast<int&>(ANativeWindow::maxSwapInterval) = - fbDev->maxSwapInterval; - } else { - ALOGE("Couldn't get gralloc module"); - } - - ANativeWindow::setSwapInterval = setSwapInterval; - ANativeWindow::dequeueBuffer = dequeueBuffer; - ANativeWindow::queueBuffer = queueBuffer; - ANativeWindow::query = query; - ANativeWindow::perform = perform; - - ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED; - ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED; - ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED; -} - -FramebufferNativeWindow::~FramebufferNativeWindow() -{ - if (grDev) { - for(int i = 0; i < mNumBuffers; i++) { - if (buffers[i] != NULL) { - grDev->free(grDev, buffers[i]->handle); - } - } - gralloc_close(grDev); - } - - if (fbDev) { - framebuffer_close(fbDev); - } -} - -status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r) -{ - if (!mUpdateOnDemand) { - return INVALID_OPERATION; - } - return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height()); -} - -status_t FramebufferNativeWindow::compositionComplete() -{ - if (fbDev->compositionComplete) { - return fbDev->compositionComplete(fbDev); - } - return INVALID_OPERATION; -} - -int FramebufferNativeWindow::setSwapInterval( - ANativeWindow* window, int interval) -{ - framebuffer_device_t* fb = getSelf(window)->fbDev; - return fb->setSwapInterval(fb, interval); -} - -void FramebufferNativeWindow::dump(String8& result) { - if (fbDev->common.version >= 1 && fbDev->dump) { - const size_t SIZE = 4096; - char buffer[SIZE]; - - fbDev->dump(fbDev, buffer, SIZE); - result.append(buffer); - } -} - -// only for debugging / logging -int FramebufferNativeWindow::getCurrentBufferIndex() const -{ - Mutex::Autolock _l(mutex); - const int index = mCurrentBufferIndex; - return index; -} - -int FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer** buffer) -{ - int fenceFd = -1; - int result = dequeueBuffer(window, buffer, &fenceFd); - sp<Fence> fence(new Fence(fenceFd)); - int waitResult = fence->wait(Fence::TIMEOUT_NEVER); - if (waitResult != OK) { - ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an " - "error: %d", waitResult); - return waitResult; - } - return result; -} - -int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, - ANativeWindowBuffer** buffer, int* fenceFd) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - - int index = self->mBufferHead++; - if (self->mBufferHead >= self->mNumBuffers) - self->mBufferHead = 0; - - // wait for a free non-front buffer - while (self->mNumFreeBuffers < 2) { - self->mCondition.wait(self->mutex); - } - ALOG_ASSERT(self->buffers[index] != self->front, ""); - - // get this buffer - self->mNumFreeBuffers--; - self->mCurrentBufferIndex = index; - - *buffer = self->buffers[index].get(); - *fenceFd = -1; - - return 0; -} - -int FramebufferNativeWindow::lockBuffer_DEPRECATED(ANativeWindow* /*window*/, - ANativeWindowBuffer* /*buffer*/) -{ - return NO_ERROR; -} - -int FramebufferNativeWindow::queueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer) -{ - return queueBuffer(window, buffer, -1); -} - -int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - framebuffer_device_t* fb = self->fbDev; - buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle; - - sp<Fence> fence(new Fence(fenceFd)); - fence->wait(Fence::TIMEOUT_NEVER); - - int res = fb->post(fb, handle); - self->front = static_cast<NativeBuffer*>(buffer); - self->mNumFreeBuffers++; - self->mCondition.broadcast(); - return res; -} - -int FramebufferNativeWindow::query(const ANativeWindow* window, - int what, int* value) -{ - const FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - framebuffer_device_t* fb = self->fbDev; - switch (what) { - case NATIVE_WINDOW_WIDTH: - *value = static_cast<int>(fb->width); - return NO_ERROR; - case NATIVE_WINDOW_HEIGHT: - *value = static_cast<int>(fb->height); - return NO_ERROR; - case NATIVE_WINDOW_FORMAT: - *value = fb->format; - return NO_ERROR; - case NATIVE_WINDOW_CONCRETE_TYPE: - *value = NATIVE_WINDOW_FRAMEBUFFER; - return NO_ERROR; - case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: - *value = 0; - return NO_ERROR; - case NATIVE_WINDOW_DEFAULT_WIDTH: - *value = static_cast<int>(fb->width); - return NO_ERROR; - case NATIVE_WINDOW_DEFAULT_HEIGHT: - *value = static_cast<int>(fb->height); - return NO_ERROR; - case NATIVE_WINDOW_TRANSFORM_HINT: - *value = 0; - return NO_ERROR; - } - *value = 0; - return BAD_VALUE; -} - -int FramebufferNativeWindow::perform(ANativeWindow* /*window*/, - int operation, ...) -{ - switch (operation) { - case NATIVE_WINDOW_CONNECT: - case NATIVE_WINDOW_DISCONNECT: - case NATIVE_WINDOW_SET_USAGE: - case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: - case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: - case NATIVE_WINDOW_SET_BUFFERS_FORMAT: - case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: - case NATIVE_WINDOW_API_CONNECT: - case NATIVE_WINDOW_API_DISCONNECT: - // TODO: we should implement these - return NO_ERROR; - - case NATIVE_WINDOW_LOCK: - case NATIVE_WINDOW_UNLOCK_AND_POST: - case NATIVE_WINDOW_SET_CROP: - case NATIVE_WINDOW_SET_BUFFER_COUNT: - case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: - case NATIVE_WINDOW_SET_SCALING_MODE: - return INVALID_OPERATION; - } - return NAME_NOT_FOUND; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- - -using android::sp; -using android::FramebufferNativeWindow; - -EGLNativeWindowType android_createDisplaySurface(void) -{ - FramebufferNativeWindow* w; - w = new FramebufferNativeWindow(); - if (w->getDevice() == NULL) { - // get a ref so it can be destroyed when we exit this block - sp<FramebufferNativeWindow> ref(w); - return NULL; - } - return static_cast<EGLNativeWindowType>(w); -} |