Merge changes I81297d6c,Id974ffb2,I8654961f
* changes:
vulkan: enable shared buffer mode and auto refresh if desired
vulkan: Set front buffer bit for image creation
vulkan: Offer frontbuffered present modes
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 99024c3..efc050b 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -20,6 +20,7 @@
libbase \
libbinder \
libcutils \
+ libdebuggerd_client \
libdumpstateaidl \
libdumpstateutil \
liblog \
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 6cc430d..c6dfa37 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -45,9 +45,9 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <cutils/debugger.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
+#include <debuggerd/client.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -864,9 +864,9 @@
}
/* create a new, empty traces.txt file to receive stack dumps */
- int fd = TEMP_FAILURE_RETRY(open(traces_path.c_str(),
- O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
- 0666)); /* -rw-rw-rw- */
+ int fd = TEMP_FAILURE_RETRY(
+ open(traces_path.c_str(), O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
+ 0666)); /* -rw-rw-rw- */
if (fd < 0) {
MYLOGE("%s: %s\n", traces_path.c_str(), strerror(errno));
return nullptr;
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index edcb3e9..987e8da 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -16,6 +16,8 @@
#include "InstalldNativeService.h"
+#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
+
#include <errno.h>
#include <inttypes.h>
#include <fstream>
@@ -46,6 +48,7 @@
#include <private/android_filesystem_config.h>
#include <selinux/android.h>
#include <system/thread_defs.h>
+#include <utils/Trace.h>
#include "dexopt.h"
#include "globals.h"
@@ -60,6 +63,7 @@
#endif
using android::base::StringPrintf;
+using std::endl;
namespace android {
namespace installd {
@@ -189,15 +193,22 @@
}
status_t InstalldNativeService::dump(int fd, const Vector<String16> & /* args */) {
+ auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
const binder::Status dump_permission = checkPermission(kDump);
if (!dump_permission.isOk()) {
- const String8 msg(dump_permission.toString8());
- write(fd, msg.string(), msg.size());
+ out << dump_permission.toString8() << endl;
return PERMISSION_DENIED;
}
+ std::lock_guard<std::recursive_mutex> lock(mLock);
- std::string msg = "installd is happy\n";
- write(fd, msg.c_str(), strlen(msg.c_str()));
+ out << "installd is happy!" << endl << endl;
+ out << "Devices with quota support:" << endl;
+ for (const auto& n : mQuotaDevices) {
+ out << " " << n.first << " = " << n.second << endl;
+ }
+ out << endl;
+ out.flush();
+
return NO_ERROR;
}
@@ -889,28 +900,6 @@
}
#endif
-static std::string findDeviceForUuid(const std::unique_ptr<std::string>& uuid) {
- auto path = create_data_path(uuid ? uuid->c_str() : nullptr);
- std::ifstream in("/proc/mounts");
- if (!in.is_open()) {
- PLOG(ERROR) << "Failed to read mounts";
- return "";
- }
- std::string source;
- std::string target;
- while (!in.eof()) {
- std::getline(in, source, ' ');
- std::getline(in, target, ' ');
- if (target == path) {
- return source;
- }
- // Skip to next line
- std::getline(in, source);
- }
- PLOG(ERROR) << "Failed to resolve block device for " << path;
- return "";
-}
-
static void collectQuotaStats(const std::string& device, int32_t userId,
int32_t appId, struct stats* stats, struct stats* extStats ATTRIBUTE_UNUSED) {
if (device.empty()) return;
@@ -965,11 +954,6 @@
#endif
}
-static void collectQuotaStats(const std::unique_ptr<std::string>& uuid, int32_t userId,
- int32_t appId, struct stats* stats, struct stats* extStats) {
- collectQuotaStats(findDeviceForUuid(uuid), userId, appId, stats, extStats);
-}
-
static void collectManualStats(const std::string& path, struct stats* stats) {
DIR *d;
int dfd;
@@ -1091,56 +1075,73 @@
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
+ auto device = findQuotaDeviceForUuid(uuid);
+ if (device.empty()) {
+ flags &= ~FLAG_USE_QUOTA;
+ }
+
+ ATRACE_BEGIN("obb");
for (auto packageName : packageNames) {
auto obbCodePath = create_data_media_obb_path(uuid_, packageName.c_str());
calculate_tree_size(obbCodePath, &extStats.codeSize);
}
+ ATRACE_END();
if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START) {
+ ATRACE_BEGIN("code");
for (auto codePath : codePaths) {
calculate_tree_size(codePath, &stats.codeSize, -1,
multiuser_get_shared_gid(userId, appId));
}
+ ATRACE_END();
- collectQuotaStats(uuid, userId, appId, &stats, &extStats);
+ ATRACE_BEGIN("quota");
+ collectQuotaStats(device, userId, appId, &stats, &extStats);
+ ATRACE_END();
} else {
+ ATRACE_BEGIN("code");
for (auto codePath : codePaths) {
calculate_tree_size(codePath, &stats.codeSize);
}
+ ATRACE_END();
for (size_t i = 0; i < packageNames.size(); i++) {
const char* pkgname = packageNames[i].c_str();
+ ATRACE_BEGIN("data");
auto cePath = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInodes[i]);
collectManualStats(cePath, &stats);
-
auto dePath = create_data_user_de_package_path(uuid_, userId, pkgname);
collectManualStats(dePath, &stats);
+ ATRACE_END();
+ ATRACE_BEGIN("profiles");
auto userProfilePath = create_data_user_profile_package_path(userId, pkgname);
calculate_tree_size(userProfilePath, &stats.dataSize);
-
auto refProfilePath = create_data_ref_profile_package_path(pkgname);
calculate_tree_size(refProfilePath, &stats.codeSize);
+ ATRACE_END();
#if MEASURE_EXTERNAL
+ ATRACE_BEGIN("external");
auto extPath = create_data_media_package_path(uuid_, userId, pkgname, "data");
collectManualStats(extPath, &extStats);
-
auto mediaPath = create_data_media_package_path(uuid_, userId, pkgname, "media");
calculate_tree_size(mediaPath, &extStats.dataSize);
+ ATRACE_END();
#endif
}
+ ATRACE_BEGIN("dalvik");
int32_t sharedGid = multiuser_get_shared_gid(userId, appId);
if (sharedGid != -1) {
calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
sharedGid, -1);
}
-
calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize,
multiuser_get_uid(userId, appId), -1);
+ ATRACE_END();
}
std::vector<int64_t> ret;
@@ -1178,35 +1179,49 @@
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
+ ATRACE_BEGIN("obb");
auto obbPath = create_data_path(uuid_) + "/media/obb";
calculate_tree_size(obbPath, &extStats.codeSize);
+ ATRACE_END();
+
+ auto device = findQuotaDeviceForUuid(uuid);
+ if (device.empty()) {
+ flags &= ~FLAG_USE_QUOTA;
+ }
if (flags & FLAG_USE_QUOTA) {
+ ATRACE_BEGIN("code");
calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
+ ATRACE_END();
+ ATRACE_BEGIN("data");
auto cePath = create_data_user_ce_path(uuid_, userId);
collectManualStatsForUser(cePath, &stats, true);
-
auto dePath = create_data_user_de_path(uuid_, userId);
collectManualStatsForUser(dePath, &stats, true);
+ ATRACE_END();
+ ATRACE_BEGIN("profile");
auto userProfilePath = create_data_user_profile_path(userId);
calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
-
auto refProfilePath = create_data_ref_profile_path();
calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
+ ATRACE_END();
#if MEASURE_EXTERNAL
+ ATRACE_BEGIN("external");
// TODO: measure external storage paths
+ ATRACE_END();
#endif
+ ATRACE_BEGIN("dalvik");
calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
-1, -1, true);
-
calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize,
-1, -1, true);
+ ATRACE_END();
- auto device = findDeviceForUuid(uuid);
+ ATRACE_BEGIN("quota");
for (auto appId : appIds) {
if (appId >= AID_APP_START) {
collectQuotaStats(device, userId, appId, &stats, &extStats);
@@ -1216,28 +1231,36 @@
#endif
}
}
+ ATRACE_END();
} else {
+ ATRACE_BEGIN("code");
calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
+ ATRACE_END();
+ ATRACE_BEGIN("data");
auto cePath = create_data_user_ce_path(uuid_, userId);
collectManualStatsForUser(cePath, &stats);
-
auto dePath = create_data_user_de_path(uuid_, userId);
collectManualStatsForUser(dePath, &stats);
+ ATRACE_END();
+ ATRACE_BEGIN("profile");
auto userProfilePath = create_data_user_profile_path(userId);
calculate_tree_size(userProfilePath, &stats.dataSize);
-
auto refProfilePath = create_data_ref_profile_path();
calculate_tree_size(refProfilePath, &stats.codeSize);
+ ATRACE_END();
#if MEASURE_EXTERNAL
+ ATRACE_BEGIN("external");
// TODO: measure external storage paths
+ ATRACE_END();
#endif
+ ATRACE_BEGIN("dalvik");
calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
-
calculate_tree_size(create_data_misc_foreign_dex_path(userId), &stats.dataSize);
+ ATRACE_END();
}
std::vector<int64_t> ret;
@@ -1274,11 +1297,14 @@
int64_t videoSize = 0;
int64_t imageSize = 0;
+ auto device = findQuotaDeviceForUuid(uuid);
+ if (device.empty()) {
+ flags &= ~FLAG_USE_QUOTA;
+ }
+
if (flags & FLAG_USE_QUOTA) {
struct dqblk dq;
- auto device = findDeviceForUuid(uuid);
-
uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
reinterpret_cast<char*>(&dq)) != 0) {
@@ -1777,5 +1803,42 @@
return res ? ok() : error();
}
+binder::Status InstalldNativeService::invalidateMounts() {
+ ENFORCE_UID(AID_SYSTEM);
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+
+ mQuotaDevices.clear();
+
+ std::ifstream in("/proc/mounts");
+ if (!in.is_open()) {
+ return error("Failed to read mounts");
+ }
+
+ std::string source;
+ std::string target;
+ std::string ignored;
+ struct dqblk dq;
+ while (!in.eof()) {
+ std::getline(in, source, ' ');
+ std::getline(in, target, ' ');
+ std::getline(in, ignored);
+
+ if (source.compare(0, 11, "/dev/block/") == 0) {
+ if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0,
+ reinterpret_cast<char*>(&dq)) == 0) {
+ LOG(DEBUG) << "Found " << source << " with quota";
+ mQuotaDevices[target] = source;
+ }
+ }
+ }
+ return ok();
+}
+
+std::string InstalldNativeService::findQuotaDeviceForUuid(
+ const std::unique_ptr<std::string>& uuid) {
+ auto path = create_data_path(uuid ? uuid->c_str() : nullptr);
+ return mQuotaDevices[path];
+}
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index ec81462..0208fb1 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <vector>
+#include <unordered_map>
#include <binder/BinderService.h>
#include <cutils/multiuser.h>
@@ -100,8 +101,15 @@
binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
const std::string& outputPath);
+ binder::Status invalidateMounts();
+
private:
std::recursive_mutex mLock;
+
+ /* Map from mount point to underlying device node */
+ std::unordered_map<std::string, std::string> mQuotaDevices;
+
+ std::string findQuotaDeviceForUuid(const std::unique_ptr<std::string>& uuid);
};
} // namespace installd
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 6e4d7fa..2f12ea9 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -68,4 +68,6 @@
@utf8InCpp String outputPath);
void deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
@utf8InCpp String outputPath);
+
+ void invalidateMounts();
}
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 76d5695..1565d0d 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -904,7 +904,7 @@
//
// Usage example:
//
-// Dex2oatFileWrapper<std::function<void ()>> file(open(...),
+// Dex2oatFileWrapper file(open(...),
// [name]() {
// unlink(name.c_str());
// });
@@ -927,14 +927,30 @@
// // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run
// // (leaving the file around; after the fd is closed).
//
-template <typename Cleanup>
class Dex2oatFileWrapper {
public:
- Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true) {
+ Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true), auto_close_(true) {
}
- Dex2oatFileWrapper(int value, Cleanup cleanup)
- : value_(value), cleanup_(cleanup), do_cleanup_(true) {}
+ Dex2oatFileWrapper(int value, std::function<void ()> cleanup)
+ : value_(value), cleanup_(cleanup), do_cleanup_(true), auto_close_(true) {}
+
+ Dex2oatFileWrapper(Dex2oatFileWrapper&& other) {
+ value_ = other.value_;
+ cleanup_ = other.cleanup_;
+ do_cleanup_ = other.do_cleanup_;
+ auto_close_ = other.auto_close_;
+ other.release();
+ }
+
+ Dex2oatFileWrapper& operator=(Dex2oatFileWrapper&& other) {
+ value_ = other.value_;
+ cleanup_ = other.cleanup_;
+ do_cleanup_ = other.do_cleanup_;
+ auto_close_ = other.auto_close_;
+ other.release();
+ return *this;
+ }
~Dex2oatFileWrapper() {
reset(-1);
@@ -949,7 +965,7 @@
}
void reset(int new_value) {
- if (value_ >= 0) {
+ if (auto_close_ && value_ >= 0) {
close(value_);
}
if (do_cleanup_ && cleanup_ != nullptr) {
@@ -959,8 +975,8 @@
value_ = new_value;
}
- void reset(int new_value, Cleanup new_cleanup) {
- if (value_ >= 0) {
+ void reset(int new_value, std::function<void ()> new_cleanup) {
+ if (auto_close_ && value_ >= 0) {
close(value_);
}
if (do_cleanup_ && cleanup_ != nullptr) {
@@ -971,77 +987,125 @@
cleanup_ = new_cleanup;
}
+ void DisableAutoClose() {
+ auto_close_ = false;
+ }
+
private:
+ void release() {
+ value_ = -1;
+ do_cleanup_ = false;
+ cleanup_ = nullptr;
+ }
int value_;
- Cleanup cleanup_;
+ std::function<void ()> cleanup_;
bool do_cleanup_;
+ bool auto_close_;
};
-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,const char* compiler_filter,
- const char* volume_uuid ATTRIBUTE_UNUSED, const char* shared_libraries) {
- bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0);
- bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
- bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
- bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
- bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
+// (re)Creates the app image if needed.
+Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path, bool profile_guided,
+ bool is_public, int uid) {
+ // Use app images only if it is enabled (by a set image format) and we are compiling
+ // profile-guided (so the app image doesn't conservatively contain all classes).
+ if (!profile_guided) {
+ return Dex2oatFileWrapper();
+ }
- CHECK(pkgname != nullptr);
- CHECK(pkgname[0] != 0);
+ const std::string image_path = create_image_filename(out_oat_path);
+ if (image_path.empty()) {
+ // Happens when the out_oat_path has an unknown extension.
+ return Dex2oatFileWrapper();
+ }
+ char app_image_format[kPropertyValueMax];
+ bool have_app_image_format =
+ get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
+ if (!have_app_image_format) {
+ return Dex2oatFileWrapper();
+ }
+ // Recreate is true since we do not want to modify a mapped image. If the app is
+ // already running and we modify the image file, it can cause crashes (b/27493510).
+ Dex2oatFileWrapper wrapper_fd(
+ open_output_file(image_path.c_str(), true /*recreate*/, 0600 /*permissions*/),
+ [image_path]() { unlink(image_path.c_str()); });
+ if (wrapper_fd.get() < 0) {
+ // Could not create application image file. Go on since we can compile without it.
+ LOG(ERROR) << "installd could not create '" << image_path
+ << "' for image file during dexopt";
+ // If we have a valid image file path but no image fd, explicitly erase the image file.
+ if (unlink(image_path.c_str()) < 0) {
+ if (errno != ENOENT) {
+ PLOG(ERROR) << "Couldn't unlink image file " << image_path;
+ }
+ }
+ } else if (!set_permissions_and_ownership(
+ wrapper_fd.get(), is_public, uid, image_path.c_str())) {
+ ALOGE("installd cannot set owner '%s' for image during dexopt\n", image_path.c_str());
+ wrapper_fd.reset(-1);
+ }
+ return wrapper_fd;
+}
+
+// Creates the dexopt swap file if necessary and return its fd.
+// Returns -1 if there's no need for a swap or in case of errors.
+base::unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) {
+ if (!ShouldUseSwapFileForDexopt()) {
+ return base::unique_fd();
+ }
+ // Make sure there really is enough space.
+ char swap_file_name[PKG_PATH_MAX];
+ strcpy(swap_file_name, out_oat_path);
+ if (!add_extension_to_file_name(swap_file_name, ".swap")) {
+ return base::unique_fd();
+ }
+ base::unique_fd swap_fd(open_output_file(
+ swap_file_name, /*recreate*/true, /*permissions*/0600));
+ if (swap_fd.get() < 0) {
+ // Could not create swap file. Optimistically go on and hope that we can compile
+ // without it.
+ ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
+ } else {
+ // Immediately unlink. We don't really want to hit flash.
+ if (unlink(swap_file_name) < 0) {
+ PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
+ }
+ }
+ return swap_fd;
+}
+
+// Opens the reference profiles if needed.
+// Note that the reference profile might not exist so it's OK if the fd will be -1.
+Dex2oatFileWrapper maybe_open_reference_profile(const char* pkgname, bool profile_guided,
+ bool is_public, int uid) {
// Public apps should not be compiled with profile information ever. Same goes for the special
// package '*' used for the system server.
- Dex2oatFileWrapper<std::function<void ()>> reference_profile_fd;
- if (!is_public && pkgname[0] != '*') {
+ if (profile_guided && !is_public && (pkgname[0] != '*')) {
// Open reference profile in read only mode as dex2oat does not get write permissions.
const std::string pkgname_str(pkgname);
- reference_profile_fd.reset(open_reference_profile(uid, pkgname, /*read_write*/ false),
- [pkgname_str]() {
- clear_reference_profile(pkgname_str.c_str());
- });
- // Note: it's OK to not find a profile here.
+ return Dex2oatFileWrapper(
+ open_reference_profile(uid, pkgname, /*read_write*/ false),
+ [pkgname_str]() {
+ clear_reference_profile(pkgname_str.c_str());
+ });
+ } else {
+ return Dex2oatFileWrapper();
}
+}
- if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
- LOG_FATAL("dexopt flags contains unknown fields\n");
- }
-
- char out_oat_path[PKG_PATH_MAX];
- if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_oat_path)) {
- return false;
- }
-
- const char *input_file = apk_path;
- struct stat input_stat;
- memset(&input_stat, 0, sizeof(input_stat));
- stat(input_file, &input_stat);
-
- // Open the input file.
- base::unique_fd input_fd(open(input_file, O_RDONLY, 0));
- if (input_fd.get() < 0) {
- ALOGE("installd cannot open '%s' for input during dexopt\n", input_file);
- return -1;
- }
-
- // Create the output OAT file.
- const std::string out_oat_path_str(out_oat_path);
- Dex2oatFileWrapper<std::function<void ()>> out_oat_fd(
- open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
- [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
- if (out_oat_fd.get() < 0) {
- ALOGE("installd cannot open '%s' for output during dexopt\n", out_oat_path);
- return -1;
- }
- if (!set_permissions_and_ownership(out_oat_fd.get(), is_public, uid, out_oat_path)) {
- return -1;
- }
-
+// Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to
+// out_vdex_wrapper_fd. Returns true for success or false in case of errors.
+bool open_vdex_files(const char* apk_path, const char* out_oat_path, int dexopt_needed,
+ const char* instruction_set, bool is_public, int uid,
+ Dex2oatFileWrapper* in_vdex_wrapper_fd,
+ Dex2oatFileWrapper* out_vdex_wrapper_fd) {
+ CHECK(in_vdex_wrapper_fd != nullptr);
+ CHECK(out_vdex_wrapper_fd != nullptr);
// Open the existing VDEX. We do this before creating the new output VDEX, which will
// unlink the old one.
char in_odex_path[PKG_PATH_MAX];
int dexopt_action = abs(dexopt_needed);
bool is_odex_location = dexopt_needed < 0;
- base::unique_fd in_vdex_fd;
std::string in_vdex_path_str;
if (dexopt_action != DEX2OAT_FROM_SCRATCH) {
// Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd.
@@ -1051,7 +1115,7 @@
path = in_odex_path;
} else {
ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path);
- return -1;
+ return false;
}
} else {
path = out_oat_path;
@@ -1059,108 +1123,138 @@
in_vdex_path_str = create_vdex_filename(path);
if (in_vdex_path_str.empty()) {
ALOGE("installd cannot compute input vdex location for '%s'\n", path);
- return -1;
+ return false;
}
if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) {
// When we dex2oat because iof boot image change, we are going to update
// in-place the vdex file.
- in_vdex_fd.reset(open(in_vdex_path_str.c_str(), O_RDWR, 0));
+ in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0));
} else {
- in_vdex_fd.reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
+ in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
}
}
// Infer the name of the output VDEX and create it.
- const std::string out_vdex_path_str = create_vdex_filename(out_oat_path_str);
+ const std::string out_vdex_path_str = create_vdex_filename(out_oat_path);
if (out_vdex_path_str.empty()) {
- return -1;
+ return false;
}
- Dex2oatFileWrapper<std::function<void ()>> out_vdex_wrapper_fd;
- int out_vdex_fd = -1;
// If we are compiling because the boot image is out of date, we do not
// need to recreate a vdex, and can use the same existing one.
if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE &&
- in_vdex_fd != -1 &&
+ in_vdex_wrapper_fd->get() != -1 &&
in_vdex_path_str == out_vdex_path_str) {
- out_vdex_fd = in_vdex_fd;
+ out_vdex_wrapper_fd->reset(in_vdex_wrapper_fd->get());
+ // Disable auto close for the in wrapper fd (it will be done when destructing the out
+ // wrapper).
+ in_vdex_wrapper_fd->DisableAutoClose();
} else {
- out_vdex_wrapper_fd.reset(
+ out_vdex_wrapper_fd->reset(
open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
[out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
- out_vdex_fd = out_vdex_wrapper_fd.get();
- if (out_vdex_fd < 0) {
- ALOGE("installd cannot open '%s' for output during dexopt\n", out_vdex_path_str.c_str());
- return -1;
+ if (out_vdex_wrapper_fd->get() < 0) {
+ ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str());
+ return false;
}
}
- if (!set_permissions_and_ownership(out_vdex_fd, is_public,
- uid, out_vdex_path_str.c_str())) {
+ if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid,
+ out_vdex_path_str.c_str())) {
+ ALOGE("installd cannot set owner '%s' for vdex during dexopt\n", out_vdex_path_str.c_str());
+ return false;
+ }
+
+ // If we got here we successfully opened the vdex files.
+ return true;
+}
+
+// Opens the output oat file for the given apk.
+// If successful it stores the output path into out_oat_path and returns true.
+Dex2oatFileWrapper open_oat_out_file(const char* apk_path, const char* oat_dir,
+ bool is_public, int uid, const char* instruction_set, char* out_oat_path) {
+ if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_oat_path)) {
+ return Dex2oatFileWrapper();
+ }
+ const std::string out_oat_path_str(out_oat_path);
+ Dex2oatFileWrapper wrapper_fd(
+ open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
+ [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
+ if (wrapper_fd.get() < 0) {
+ ALOGE("installd cannot open '%s' for output during dexopt\n", out_oat_path);
+ } else if (!set_permissions_and_ownership(wrapper_fd.get(), is_public, uid, out_oat_path)) {
+ ALOGE("installd cannot set owner '%s' for output during dexopt\n", out_oat_path);
+ wrapper_fd.reset(-1);
+ }
+ return wrapper_fd;
+}
+
+// Updates the access times of out_oat_path based on those from apk_path.
+void update_out_oat_access_times(const char* apk_path, const char* out_oat_path) {
+ struct stat input_stat;
+ memset(&input_stat, 0, sizeof(input_stat));
+ if (stat(apk_path, &input_stat) != 0) {
+ PLOG(ERROR) << "Could not stat " << apk_path << " during dexopt";
+ return;
+ }
+
+ struct utimbuf ut;
+ ut.actime = input_stat.st_atime;
+ ut.modtime = input_stat.st_mtime;
+ if (utime(out_oat_path, &ut) != 0) {
+ PLOG(WARNING) << "Could not update access times for " << apk_path << " during dexopt";
+ }
+}
+
+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,const char* compiler_filter,
+ const char* volume_uuid ATTRIBUTE_UNUSED, const char* shared_libraries) {
+ CHECK(pkgname != nullptr);
+ CHECK(pkgname[0] != 0);
+ if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
+ LOG_FATAL("dexopt flags contains unknown fields\n");
+ }
+
+ bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0);
+ bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
+ bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
+ bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
+ bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
+
+ // Open the input file.
+ base::unique_fd input_fd(open(apk_path, O_RDONLY, 0));
+ if (input_fd.get() < 0) {
+ ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path);
+ return -1;
+ }
+
+ // Create the output OAT file.
+ char out_oat_path[PKG_PATH_MAX];
+ Dex2oatFileWrapper out_oat_fd = open_oat_out_file(apk_path, oat_dir, is_public, uid,
+ instruction_set, out_oat_path);
+ if (out_oat_fd.get() < 0) {
+ return -1;
+ }
+
+ // Open vdex files.
+ Dex2oatFileWrapper in_vdex_fd;
+ Dex2oatFileWrapper out_vdex_fd;
+ if (!open_vdex_files(apk_path, out_oat_path, dexopt_needed, instruction_set, is_public, uid,
+ &in_vdex_fd, &out_vdex_fd)) {
return -1;
}
// Create a swap file if necessary.
- base::unique_fd swap_fd;
- if (ShouldUseSwapFileForDexopt()) {
- // Make sure there really is enough space.
- char swap_file_name[PKG_PATH_MAX];
- strcpy(swap_file_name, out_oat_path);
- if (add_extension_to_file_name(swap_file_name, ".swap")) {
- swap_fd.reset(open_output_file(swap_file_name, /*recreate*/true, /*permissions*/0600));
- }
- if (swap_fd.get() < 0) {
- // Could not create swap file. Optimistically go on and hope that we can compile
- // without it.
- ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
- } else {
- // Immediately unlink. We don't really want to hit flash.
- if (unlink(swap_file_name) < 0) {
- PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
- }
- }
- }
+ base::unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path);
- // Avoid generating an app image for extract only since it will not contain any classes.
- Dex2oatFileWrapper<std::function<void ()>> image_fd;
- const std::string image_path = create_image_filename(out_oat_path);
- if (!image_path.empty()) {
- char app_image_format[kPropertyValueMax];
- bool have_app_image_format =
- get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
- // Use app images only if it is enabled (by a set image format) and we are compiling
- // profile-guided (so the app image doesn't conservatively contain all classes).
- if (profile_guided && have_app_image_format) {
- // Recreate is true since we do not want to modify a mapped image. If the app is
- // already running and we modify the image file, it can cause crashes (b/27493510).
- image_fd.reset(open_output_file(image_path.c_str(),
- true /*recreate*/,
- 0600 /*permissions*/),
- [image_path]() { unlink(image_path.c_str()); }
- );
- if (image_fd.get() < 0) {
- // Could not create application image file. Go on since we can compile without
- // it.
- LOG(ERROR) << "installd could not create '"
- << image_path
- << "' for image file during dexopt";
- } else if (!set_permissions_and_ownership(image_fd.get(),
- is_public,
- uid,
- image_path.c_str())) {
- image_fd.reset(-1);
- }
- }
- // If we have a valid image file path but no image fd, explicitly erase the image file.
- if (image_fd.get() < 0) {
- if (unlink(image_path.c_str()) < 0) {
- if (errno != ENOENT) {
- PLOG(ERROR) << "Couldn't unlink image file " << image_path;
- }
- }
- }
- }
+ // Create the app image file if needed.
+ Dex2oatFileWrapper image_fd =
+ maybe_open_app_image(out_oat_path, profile_guided, is_public, uid);
- ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
+ // Open the reference profile if needed.
+ Dex2oatFileWrapper reference_profile_fd =
+ maybe_open_reference_profile(pkgname, profile_guided, is_public, uid);
+
+ ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);
pid_t pid = fork();
if (pid == 0) {
@@ -1174,11 +1268,11 @@
}
// Pass dex2oat the relative path to the input file.
- const char *input_file_name = get_location_from_path(input_file);
+ const char *input_file_name = get_location_from_path(apk_path);
run_dex2oat(input_fd.get(),
out_oat_fd.get(),
in_vdex_fd.get(),
- out_vdex_fd,
+ out_vdex_fd.get(),
image_fd.get(),
input_file_name,
out_oat_path,
@@ -1194,21 +1288,18 @@
} else {
int res = wait_child(pid);
if (res == 0) {
- ALOGV("DexInv: --- END '%s' (success) ---\n", input_file);
+ ALOGV("DexInv: --- END '%s' (success) ---\n", apk_path);
} else {
- ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", input_file, res);
+ ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", apk_path, res);
return -1;
}
}
- struct utimbuf ut;
- ut.actime = input_stat.st_atime;
- ut.modtime = input_stat.st_mtime;
- utime(out_oat_path, &ut);
+ update_out_oat_access_times(apk_path, out_oat_path);
// We've been successful, don't delete output.
out_oat_fd.SetCleanup(false);
- out_vdex_wrapper_fd.SetCleanup(false);
+ out_vdex_fd.SetCleanup(false);
image_fd.SetCleanup(false);
reference_profile_fd.SetCleanup(false);
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index a31e3c7..43c4c8b 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -363,6 +363,7 @@
int main()
{
struct binder_state *bs;
+ union selinux_callback cb;
bs = binder_open(128*1024);
if (!bs) {
@@ -375,6 +376,11 @@
return -1;
}
+ cb.func_audit = audit_callback;
+ selinux_set_callback(SELINUX_CB_AUDIT, cb);
+ cb.func_log = selinux_log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
+
sehandle = selinux_android_service_context_handle();
selinux_status_open(true);
@@ -388,11 +394,6 @@
abort();
}
- union selinux_callback cb;
- cb.func_audit = audit_callback;
- selinux_set_callback(SELINUX_CB_AUDIT, cb);
- cb.func_log = selinux_log_callback;
- selinux_set_callback(SELINUX_CB_LOG, cb);
binder_loop(bs, svcmgr_handler);
diff --git a/include/audiomanager/AudioManager.h b/include/audiomanager/AudioManager.h
index d561594..834dcbd 100644
--- a/include/audiomanager/AudioManager.h
+++ b/include/audiomanager/AudioManager.h
@@ -23,19 +23,19 @@
#define PLAYER_PIID_INVALID -1
-enum {
+typedef enum {
PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE = 11,
PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD = 12,
-};
+} player_type_t;
-enum {
+typedef enum {
PLAYER_STATE_UNKNOWN = -1,
PLAYER_STATE_RELEASED = 0,
PLAYER_STATE_IDLE = 1,
PLAYER_STATE_STARTED = 2,
PLAYER_STATE_PAUSED = 3,
PLAYER_STATE_STOPPED = 4,
-};
+} player_state_t;
}; // namespace android
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index f5ea259..909318a 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -114,10 +114,12 @@
// The parcels created by these methods must be kept in sync with the
// corresponding methods from IAudioService.aidl and objects it imports.
- virtual audio_unique_id_t trackPlayer(int playerType, int usage, int content) = 0;
- /*oneway*/ virtual status_t playerAttributes(audio_unique_id_t piid, int usage, int content)= 0;
- /*oneway*/ virtual status_t playerEvent(int piid, int event) = 0;
- /*oneway*/ virtual status_t releasePlayer(int piid) = 0;
+ virtual audio_unique_id_t trackPlayer(player_type_t playerType, audio_usage_t usage,
+ audio_content_type_t content, const sp<IBinder>& player) = 0;
+ /*oneway*/ virtual status_t playerAttributes(audio_unique_id_t piid, audio_usage_t usage,
+ audio_content_type_t content)= 0;
+ /*oneway*/ virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event) = 0;
+ /*oneway*/ virtual status_t releasePlayer(audio_unique_id_t piid) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/audiomanager/IPlayer.h b/include/audiomanager/IPlayer.h
new file mode 100644
index 0000000..efcac74
--- /dev/null
+++ b/include/audiomanager/IPlayer.h
@@ -0,0 +1,61 @@
+/*
+ * 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 ANDROID_IPLAYER_H
+#define ANDROID_IPLAYER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IPlayer : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(Player);
+
+ virtual void start() = 0;
+
+ virtual void pause() = 0;
+
+ virtual void stop() = 0;
+
+ virtual void setVolume(float vol) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+
+class BnPlayer : public BnInterface<IPlayer>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IPLAYER_H
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index a69de5e..9cb2035 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -219,7 +219,10 @@
break;
case SENSOR_TYPE_DYNAMIC_SENSOR_META:
mStringType = SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META;
- mFlags = SENSOR_FLAG_SPECIAL_REPORTING_MODE; // special trigger and non-wake up
+ mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE; // special trigger
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
break;
case SENSOR_TYPE_POSE_6DOF:
mStringType = SENSOR_STRING_TYPE_POSE_6DOF;
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 493c0b8..48bf676 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -740,6 +740,7 @@
case GGL_PIXEL_FORMAT_RGB_565: size *= 2; break;
case GGL_PIXEL_FORMAT_RGBA_8888: size *= 4; break;
case GGL_PIXEL_FORMAT_RGBX_8888: size *= 4; break;
+ case GGL_PIXEL_FORMAT_BGRA_8888: size *= 4; break;
default:
ALOGE("incompatible pixel format for pbuffer (format=%d)", f);
pbuffer.data = 0;
@@ -1027,6 +1028,19 @@
{ EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};
+// BGRA 8888 config
+static config_pair_t const config_8_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 32 },
+ { EGL_ALPHA_SIZE, 8 },
+ { EGL_BLUE_SIZE, 8 },
+ { EGL_GREEN_SIZE, 8 },
+ { EGL_RED_SIZE, 8 },
+ { EGL_DEPTH_SIZE, 0 },
+ { EGL_CONFIG_ID, 8 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_BGRA_8888 },
+ { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
static configs_t const gConfigs[] = {
{ config_0_attribute_list, NELEM(config_0_attribute_list) },
{ config_1_attribute_list, NELEM(config_1_attribute_list) },
@@ -1036,6 +1050,7 @@
{ config_5_attribute_list, NELEM(config_5_attribute_list) },
{ config_6_attribute_list, NELEM(config_6_attribute_list) },
{ config_7_attribute_list, NELEM(config_7_attribute_list) },
+ { config_8_attribute_list, NELEM(config_8_attribute_list) },
};
static config_management_t const gConfigManagement[] = {
@@ -1118,6 +1133,10 @@
pixelFormat = GGL_PIXEL_FORMAT_A_8;
depthFormat = GGL_PIXEL_FORMAT_Z_16;
break;
+ case 8:
+ pixelFormat = GGL_PIXEL_FORMAT_BGRA_8888;
+ depthFormat = 0;
+ break;
default:
return NAME_NOT_FOUND;
}
diff --git a/services/audiomanager/Android.bp b/services/audiomanager/Android.bp
index 04dd967..22b084a 100644
--- a/services/audiomanager/Android.bp
+++ b/services/audiomanager/Android.bp
@@ -1,7 +1,10 @@
cc_library_shared {
name: "libaudiomanager",
- srcs: ["IAudioManager.cpp"],
+ srcs: [
+ "IAudioManager.cpp",
+ "IPlayer.cpp",
+ ],
shared_libs: [
"libutils",
diff --git a/services/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp
index a41804f..b9b0706 100644
--- a/services/audiomanager/IAudioManager.cpp
+++ b/services/audiomanager/IAudioManager.cpp
@@ -35,15 +35,16 @@
{
}
- virtual audio_unique_id_t trackPlayer(int playerType, int usage, int content) {
+ virtual audio_unique_id_t trackPlayer(player_type_t playerType, audio_usage_t usage,
+ audio_content_type_t content, const sp<IBinder>& player) {
Parcel data, reply;
data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
data.writeInt32(1); // non-null PlayerIdCard parcelable
// marshall PlayerIdCard data
data.writeInt32((int32_t) playerType);
// write attributes of PlayerIdCard
- data.writeInt32(usage);
- data.writeInt32(content);
+ data.writeInt32((int32_t) usage);
+ data.writeInt32((int32_t) content);
data.writeInt32(0 /*source: none here, this is a player*/);
data.writeInt32(0 /*flags*/);
// write attributes' tags
@@ -51,6 +52,8 @@
data.writeString16(String16("")); // no tags
// write attributes' bundle
data.writeInt32(-1977 /*ATTR_PARCEL_IS_NULL_BUNDLE*/); // no bundle
+ // write IPlayer
+ data.writeStrongBinder(player);
// get new PIId in reply
const status_t res = remote()->transact(TRACK_PLAYER, data, &reply, 0);
if (res != OK || reply.readExceptionCode() != 0) {
@@ -63,13 +66,14 @@
}
}
- virtual status_t playerAttributes(audio_unique_id_t piid, int usage, int content) {
+ virtual status_t playerAttributes(audio_unique_id_t piid, audio_usage_t usage,
+ audio_content_type_t content) {
Parcel data, reply;
data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
- data.writeInt32(piid);
+ data.writeInt32((int32_t) piid);
data.writeInt32(1); // non-null AudioAttributes parcelable
- data.writeInt32(usage);
- data.writeInt32(content);
+ data.writeInt32((int32_t) usage);
+ data.writeInt32((int32_t) content);
data.writeInt32(0 /*source: none here, this is a player*/);
data.writeInt32(0 /*flags*/);
// write attributes' tags
@@ -80,18 +84,18 @@
return remote()->transact(PLAYER_ATTRIBUTES, data, &reply, IBinder::FLAG_ONEWAY);
}
- virtual status_t playerEvent(int piid, int event) {
+ virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event) {
Parcel data, reply;
data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
- data.writeInt32(piid);
- data.writeInt32(event);
+ data.writeInt32((int32_t) piid);
+ data.writeInt32((int32_t) event);
return remote()->transact(PLAYER_EVENT, data, &reply, IBinder::FLAG_ONEWAY);
}
- virtual status_t releasePlayer(int piid) {
+ virtual status_t releasePlayer(audio_unique_id_t piid) {
Parcel data, reply;
data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
- data.writeInt32(piid);
+ data.writeInt32((int32_t) piid);
return remote()->transact(RELEASE_PLAYER, data, &reply, IBinder::FLAG_ONEWAY);
}
};
diff --git a/services/audiomanager/IPlayer.cpp b/services/audiomanager/IPlayer.cpp
new file mode 100644
index 0000000..3b0b4e9
--- /dev/null
+++ b/services/audiomanager/IPlayer.cpp
@@ -0,0 +1,109 @@
+/*
+**
+** Copyright 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.
+*/
+
+#define LOG_TAG "IPlayer"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+
+#include <audiomanager/IPlayer.h>
+
+namespace android {
+
+enum {
+ START = IBinder::FIRST_CALL_TRANSACTION,
+ PAUSE = IBinder::FIRST_CALL_TRANSACTION + 1,
+ STOP = IBinder::FIRST_CALL_TRANSACTION + 2,
+ SET_VOLUME = IBinder::FIRST_CALL_TRANSACTION + 3,
+};
+
+class BpPlayer : public BpInterface<IPlayer>
+{
+public:
+ explicit BpPlayer(const sp<IBinder>& impl)
+ : BpInterface<IPlayer>(impl)
+ {
+ }
+
+ virtual void start()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ remote()->transact(START, data, &reply);
+ }
+
+ virtual void pause()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ remote()->transact(PAUSE, data, &reply);
+ }
+
+ virtual void stop()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ remote()->transact(STOP, data, &reply);
+ }
+
+ virtual void setVolume(float vol)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ data.writeFloat(vol);
+ remote()->transact(SET_VOLUME, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(Player, "android.media.IPlayer");
+
+// ----------------------------------------------------------------------
+
+status_t BnPlayer::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch (code) {
+ case START: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ start();
+ return NO_ERROR;
+ } break;
+ case PAUSE: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ pause();
+ return NO_ERROR;
+ }
+ case STOP: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ stop();
+ return NO_ERROR;
+ } break;
+ case SET_VOLUME: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ setVolume(data.readFloat());
+ return NO_ERROR;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 89475e9..8771d45 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -1224,15 +1224,8 @@
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
&& (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
- int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
- if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
- outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
- } else if (isWindowObscuredLocked(windowHandle)) {
- outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
- }
-
mTempTouchState.addOrUpdateWindow(
- windowHandle, outsideTargetFlags, BitSet32(0));
+ windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
}
}
}