Merge "Trace drawing state"
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index f908cbf..ce3a6aa 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -24,20 +24,6 @@
],
}
-cc_library_headers {
- name: "dumpstate_headers",
- vendor_available: true,
- export_include_dirs: ["."],
- header_libs: [
- "libbase_headers",
- "libutils_headers",
- ],
- export_header_lib_headers: [
- "libbase_headers",
- "libutils_headers",
- ],
-}
-
cc_library_shared {
name: "libdumpstateutil",
defaults: ["dumpstate_defaults"],
@@ -45,8 +31,6 @@
vndk: {
enabled: true,
},
- header_libs: ["dumpstate_headers"],
- export_header_lib_headers: ["dumpstate_headers"],
srcs: [
"DumpstateInternal.cpp",
"DumpstateUtil.cpp",
@@ -55,6 +39,10 @@
"libbase",
"liblog",
],
+ export_include_dirs: ["."],
+ export_shared_lib_headers: [
+ "libbase",
+ ],
}
cc_library_shared {
@@ -78,7 +66,6 @@
cc_binary {
name: "dumpstate",
defaults: ["dumpstate_defaults"],
- header_libs: ["dumpstate_headers"],
shared_libs: [
"android.hardware.dumpstate@1.0",
"libziparchive",
@@ -106,7 +93,6 @@
cc_test {
name: "dumpstate_test",
defaults: ["dumpstate_defaults"],
- header_libs: ["dumpstate_headers"],
shared_libs: [
"libziparchive",
"libbase",
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 56470d6..bb2187a 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -18,6 +18,7 @@
shared_libs: [
"libbase",
"libbinder",
+ "libcrypto",
"libcutils",
"liblog",
"liblogwrap",
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index 1d21b3c..b3dc5ec 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -27,6 +27,7 @@
LOCAL_HEADER_LIBRARIES := dex2oat_headers
LOCAL_SHARED_LIBRARIES := \
libbase \
+ libcrypto \
libcutils \
liblog \
liblogwrap \
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 4246536..e10fb6c 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2312,6 +2312,22 @@
return result ? ok() : error();
}
+binder::Status InstalldNativeService::hashSecondaryDexFile(
+ const std::string& dexPath, const std::string& packageName, int32_t uid,
+ const std::unique_ptr<std::string>& volumeUuid, int32_t storageFlag,
+ std::vector<uint8_t>* _aidl_return) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID(volumeUuid);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+
+ // mLock is not taken here since we will never modify the file system.
+ // If a file is modified just as we are reading it this may result in an
+ // anomalous hash, but that's ok.
+ bool result = android::installd::hash_secondary_dex_file(
+ dexPath, packageName, uid, volumeUuid, storageFlag, _aidl_return);
+ return result ? ok() : error();
+}
+
binder::Status InstalldNativeService::invalidateMounts() {
ENFORCE_UID(AID_SYSTEM);
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index c8db3df..5167a14 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -115,6 +115,9 @@
binder::Status reconcileSecondaryDexFile(const std::string& dexPath,
const std::string& packageName, int32_t uid, const std::vector<std::string>& isa,
const std::unique_ptr<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return);
+ binder::Status hashSecondaryDexFile(const std::string& dexPath,
+ const std::string& packageName, int32_t uid, const std::unique_ptr<std::string>& volumeUuid,
+ int32_t storageFlag, std::vector<uint8_t>* _aidl_return);
binder::Status invalidateMounts();
binder::Status isQuotaSupported(const std::unique_ptr<std::string>& volumeUuid,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 452a2b1..0f9862d 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -82,6 +82,9 @@
int uid, in @utf8InCpp String[] isas, @nullable @utf8InCpp String volume_uuid,
int storage_flag);
+ byte[] hashSecondaryDexFile(@utf8InCpp String dexPath, @utf8InCpp String pkgName,
+ int uid, @nullable @utf8InCpp String volumeUuid, int storageFlag);
+
void invalidateMounts();
boolean isQuotaSupported(@nullable @utf8InCpp String uuid);
}
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index af2c527..6f160b9 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "installed"
+#include <array>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
@@ -27,6 +28,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
@@ -36,6 +38,7 @@
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <log/log.h> // TODO: Move everything to base/logging.
+#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
#include <selinux/android.h>
#include <system/thread_defs.h>
@@ -46,8 +49,10 @@
#include "otapreopt_utils.h"
#include "utils.h"
-using android::base::StringPrintf;
using android::base::EndsWith;
+using android::base::ReadFully;
+using android::base::StringPrintf;
+using android::base::WriteFully;
using android::base::unique_fd;
namespace android {
@@ -2052,6 +2057,90 @@
}
}
+// Compute and return the hash (SHA-256) of the secondary dex file at dex_path.
+// Returns true if all parameters are valid and the hash successfully computed and stored in
+// out_secondary_dex_hash.
+// Also returns true with an empty hash if the file does not currently exist or is not accessible to
+// the app.
+// For any other errors (e.g. if any of the parameters are invalid) returns false.
+bool hash_secondary_dex_file(const std::string& dex_path, const std::string& pkgname, int uid,
+ const std::unique_ptr<std::string>& volume_uuid, int storage_flag,
+ std::vector<uint8_t>* out_secondary_dex_hash) {
+ out_secondary_dex_hash->clear();
+
+ const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str();
+
+ if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) {
+ LOG(ERROR) << "hash_secondary_dex_file called with invalid storage_flag: "
+ << storage_flag;
+ return false;
+ }
+
+ // Pipe to get the hash result back from our child process.
+ unique_fd pipe_read, pipe_write;
+ if (!Pipe(&pipe_read, &pipe_write)) {
+ PLOG(ERROR) << "Failed to create pipe";
+ return false;
+ }
+
+ // Fork so that actual access to the files is done in the app's own UID, to ensure we only
+ // access data the app itself can access.
+ pid_t pid = fork();
+ if (pid == 0) {
+ // child -- drop privileges before continuing
+ drop_capabilities(uid);
+ pipe_read.reset();
+
+ if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr, uid, storage_flag)) {
+ LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
+ _exit(1);
+ }
+
+ unique_fd fd(TEMP_FAILURE_RETRY(open(dex_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)));
+ if (fd == -1) {
+ if (errno == EACCES || errno == ENOENT) {
+ // Not treated as an error.
+ _exit(0);
+ }
+ PLOG(ERROR) << "Failed to open secondary dex " << dex_path;
+ _exit(1);
+ }
+
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+
+ std::vector<uint8_t> buffer(65536);
+ while (true) {
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), buffer.size()));
+ if (bytes_read == 0) {
+ break;
+ } else if (bytes_read == -1) {
+ PLOG(ERROR) << "Failed to read secondary dex " << dex_path;
+ _exit(1);
+ }
+
+ SHA256_Update(&ctx, buffer.data(), bytes_read);
+ }
+
+ std::array<uint8_t, SHA256_DIGEST_LENGTH> hash;
+ SHA256_Final(hash.data(), &ctx);
+ if (!WriteFully(pipe_write, hash.data(), hash.size())) {
+ _exit(1);
+ }
+
+ _exit(0);
+ }
+
+ // parent
+ pipe_write.reset();
+
+ out_secondary_dex_hash->resize(SHA256_DIGEST_LENGTH);
+ if (!ReadFully(pipe_read, out_secondary_dex_hash->data(), out_secondary_dex_hash->size())) {
+ out_secondary_dex_hash->clear();
+ }
+ return wait_child(pid) == 0;
+}
+
// Helper for move_ab, so that we can have common failure-case cleanup.
static bool unlink_and_rename(const char* from, const char* to) {
// Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise,
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index 1f41e67..798e211 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -63,6 +63,10 @@
const std::unique_ptr<std::string>& volumeUuid, int storage_flag,
/*out*/bool* out_secondary_dex_exists);
+bool hash_secondary_dex_file(const std::string& dex_path,
+ const std::string& pkgname, int uid, const std::unique_ptr<std::string>& volume_uuid,
+ int storage_flag, std::vector<uint8_t>* out_secondary_dex_hash);
+
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, const char* class_loader_context, const char* se_info,
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 1a22992..47346fb 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -24,6 +24,7 @@
shared_libs: [
"libbase",
"libbinder",
+ "libcrypto",
"libcutils",
"libselinux",
"libutils",
@@ -44,6 +45,7 @@
shared_libs: [
"libbase",
"libbinder",
+ "libcrypto",
"libcutils",
"libselinux",
"libutils",
@@ -64,6 +66,7 @@
shared_libs: [
"libbase",
"libbinder",
+ "libcrypto",
"libcutils",
"libselinux",
"libutils",
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index ca812bd..a5af5d7 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <sys/statvfs.h>
@@ -56,16 +57,19 @@
return create_cache_path_default(path, src, instruction_set);
}
+static std::string get_full_path(const char* path) {
+ return StringPrintf("/data/local/tmp/user/0/%s", path);
+}
+
static void mkdir(const char* path, uid_t owner, gid_t group, mode_t mode) {
- const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
- ::mkdir(fullPath, mode);
- ::chown(fullPath, owner, group);
- ::chmod(fullPath, mode);
+ const std::string fullPath = get_full_path(path);
+ ::mkdir(fullPath.c_str(), mode);
+ ::chown(fullPath.c_str(), owner, group);
+ ::chmod(fullPath.c_str(), mode);
}
static void touch(const char* path, uid_t owner, gid_t group, mode_t mode) {
- int fd = ::open(StringPrintf("/data/local/tmp/user/0/%s", path).c_str(),
- O_RDWR | O_CREAT, mode);
+ int fd = ::open(get_full_path(path).c_str(), O_RDWR | O_CREAT, mode);
::fchown(fd, owner, group);
::fchmod(fd, mode);
::close(fd);
@@ -73,13 +77,13 @@
static int stat_gid(const char* path) {
struct stat buf;
- ::stat(StringPrintf("/data/local/tmp/user/0/%s", path).c_str(), &buf);
+ ::stat(get_full_path(path).c_str(), &buf);
return buf.st_gid;
}
static int stat_mode(const char* path) {
struct stat buf;
- ::stat(StringPrintf("/data/local/tmp/user/0/%s", path).c_str(), &buf);
+ ::stat(get_full_path(path).c_str(), &buf);
return buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID);
}
@@ -149,6 +153,69 @@
EXPECT_EQ(10000, stat_gid("com.example/bar/file"));
}
+TEST_F(ServiceTest, HashSecondaryDex) {
+ LOG(INFO) << "HashSecondaryDex";
+
+ mkdir("com.example", 10000, 10000, 0700);
+ mkdir("com.example/foo", 10000, 10000, 0700);
+ touch("com.example/foo/file", 10000, 20000, 0700);
+
+ std::vector<uint8_t> result;
+ std::string dexPath = get_full_path("com.example/foo/file");
+ EXPECT_TRUE(service->hashSecondaryDexFile(
+ dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result).isOk());
+
+ EXPECT_EQ(result.size(), 32U);
+
+ std::ostringstream output;
+ output << std::hex << std::setfill('0');
+ for (auto b : result) {
+ output << std::setw(2) << +b;
+ }
+
+ // This is the SHA256 of an empty string (sha256sum /dev/null)
+ EXPECT_EQ(output.str(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+}
+
+TEST_F(ServiceTest, HashSecondaryDex_NoSuch) {
+ LOG(INFO) << "HashSecondaryDex_NoSuch";
+
+ std::vector<uint8_t> result;
+ std::string dexPath = get_full_path("com.example/foo/file");
+ EXPECT_TRUE(service->hashSecondaryDexFile(
+ dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result).isOk());
+
+ EXPECT_EQ(result.size(), 0U);
+}
+
+TEST_F(ServiceTest, HashSecondaryDex_Unreadable) {
+ LOG(INFO) << "HashSecondaryDex_Unreadable";
+
+ mkdir("com.example", 10000, 10000, 0700);
+ mkdir("com.example/foo", 10000, 10000, 0700);
+ touch("com.example/foo/file", 10000, 20000, 0300);
+
+ std::vector<uint8_t> result;
+ std::string dexPath = get_full_path("com.example/foo/file");
+ EXPECT_TRUE(service->hashSecondaryDexFile(
+ dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result).isOk());
+
+ EXPECT_EQ(result.size(), 0U);
+}
+
+TEST_F(ServiceTest, HashSecondaryDex_WrongApp) {
+ LOG(INFO) << "HashSecondaryDex_WrongApp";
+
+ mkdir("com.example", 10000, 10000, 0700);
+ mkdir("com.example/foo", 10000, 10000, 0700);
+ touch("com.example/foo/file", 10000, 20000, 0700);
+
+ std::vector<uint8_t> result;
+ std::string dexPath = get_full_path("com.example/foo/file");
+ EXPECT_FALSE(service->hashSecondaryDexFile(
+ dexPath, "com.wrong", 10000, testUuid, FLAG_STORAGE_CE, &result).isOk());
+}
+
TEST_F(ServiceTest, CalculateOat) {
char buf[PKG_PATH_MAX];
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 221bc4f..ace01a6 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -9,16 +9,6 @@
namespace dvr {
/* static */
-sp<BufferHubQueueProducer> BufferHubQueueProducer::Create() {
- sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer;
- auto config = ProducerQueueConfigBuilder()
- .SetMetadata<DvrNativeBufferMetadata>()
- .Build();
- producer->queue_ = ProducerQueue::Create(config, UsagePolicy{});
- return producer;
-}
-
-/* static */
sp<BufferHubQueueProducer> BufferHubQueueProducer::Create(
const std::shared_ptr<ProducerQueue>& queue) {
if (queue->metadata_size() != sizeof(DvrNativeBufferMetadata)) {
@@ -33,6 +23,19 @@
return producer;
}
+/* static */
+sp<BufferHubQueueProducer> BufferHubQueueProducer::Create(
+ ProducerQueueParcelable parcelable) {
+ if (!parcelable.IsValid()) {
+ ALOGE("BufferHubQueueProducer::Create: Invalid producer parcelable.");
+ return nullptr;
+ }
+
+ sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer;
+ producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
+ return producer;
+}
+
status_t BufferHubQueueProducer::requestBuffer(int slot,
sp<GraphicBuffer>* buf) {
ALOGD_IF(TRACE, "requestBuffer: slot=%d", slot);
@@ -475,6 +478,13 @@
return BAD_VALUE;
}
+ if (!queue_->is_connected()) {
+ ALOGE(
+ "BufferHubQueueProducer::connect: This BufferHubQueueProducer is not "
+ "connected to bufferhud. Has it been taken out as a parcelable?");
+ return BAD_VALUE;
+ }
+
switch (api) {
case NATIVE_WINDOW_API_EGL:
case NATIVE_WINDOW_API_CPU:
@@ -617,6 +627,39 @@
return NO_ERROR;
}
+status_t BufferHubQueueProducer::TakeAsParcelable(
+ ProducerQueueParcelable* out_parcelable) {
+ if (!out_parcelable || out_parcelable->IsValid())
+ return BAD_VALUE;
+
+ if (connected_api_ != kNoConnectedApi) {
+ ALOGE(
+ "BufferHubQueueProducer::TakeAsParcelable: BufferHubQueueProducer has "
+ "connected client. Must disconnect first.");
+ return BAD_VALUE;
+ }
+
+ if (!queue_->is_connected()) {
+ ALOGE(
+ "BufferHubQueueProducer::TakeAsParcelable: This BufferHubQueueProducer "
+ "is not connected to bufferhud. Has it been taken out as a "
+ "parcelable?");
+ return BAD_VALUE;
+ }
+
+ auto status = queue_->TakeAsParcelable();
+ if (!status) {
+ ALOGE(
+ "BufferHubQueueProducer::TakeAsParcelable: Failed to take out "
+ "ProducuerQueueParcelable from the producer queue, error: %s.",
+ status.GetErrorMessage().c_str());
+ return BAD_VALUE;
+ }
+
+ *out_parcelable = status.take();
+ return NO_ERROR;
+}
+
status_t BufferHubQueueProducer::AllocateBuffer(uint32_t width, uint32_t height,
uint32_t layer_count,
PixelFormat format,
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index c8e31c7..5b320a4 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -74,7 +74,8 @@
return available_buffers_.size() >= kMaxQueueCapacity;
}
- explicit operator bool() const { return epoll_fd_.IsValid(); }
+ // Returns whether the buffer queue is connected to bufferhubd.
+ bool is_connected() const { return !!GetChannel(); }
int GetBufferId(size_t slot) const {
return (slot < buffers_.size() && buffers_[slot]) ? buffers_[slot]->id()
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
index 7ed55fb..9c85048 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
@@ -3,6 +3,7 @@
#include <gui/IGraphicBufferProducer.h>
#include <private/dvr/buffer_hub_queue_client.h>
+#include <private/dvr/buffer_hub_queue_parcelable.h>
namespace android {
namespace dvr {
@@ -17,14 +18,16 @@
// that.
static constexpr int kDefaultUndequeuedBuffers = 1;
- // Create a BufferHubQueueProducer instance by creating a new producer queue.
- static sp<BufferHubQueueProducer> Create();
-
- // Create a BufferHubQueueProducer instance by importing an existing prodcuer
+ // Creates a BufferHubQueueProducer instance by importing an existing prodcuer
// queue.
static sp<BufferHubQueueProducer> Create(
const std::shared_ptr<ProducerQueue>& producer);
+ // Creates a BufferHubQueueProducer instance by importing an existing prodcuer
+ // parcelable. Note that this call takes the ownership of the parcelable
+ // object and is guaranteed to succeed if parcelable object is valid.
+ static sp<BufferHubQueueProducer> Create(ProducerQueueParcelable parcelable);
+
// See |IGraphicBufferProducer::requestBuffer|
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
@@ -115,6 +118,14 @@
// See |IGraphicBufferProducer::getConsumerUsage|
status_t getConsumerUsage(uint64_t* out_usage) const override;
+ // Takes out the current producer as a binder parcelable object. Note that the
+ // producer must be disconnected to be exportable. After successful export,
+ // the producer queue can no longer be connected again. Returns NO_ERROR when
+ // takeout is successful and out_parcelable will hold the new parcelable
+ // object. Also note that out_parcelable cannot be NULL and must points to an
+ // invalid parcelable.
+ status_t TakeAsParcelable(ProducerQueueParcelable* out_parcelable);
+
private:
using LocalHandle = pdx::LocalHandle;
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
index 28cd63a..96f5404 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
@@ -3,12 +3,15 @@
#include <base/logging.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
+#include <pdx/default_transport/channel_parcelable.h>
#include <gtest/gtest.h>
namespace android {
namespace dvr {
+using pdx::LocalHandle;
+
namespace {
// Default dimensions before setDefaultBufferSize is called by the consumer.
@@ -92,7 +95,13 @@
ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
- mProducer = BufferHubQueueProducer::Create();
+ auto config = ProducerQueueConfigBuilder()
+ .SetMetadata<DvrNativeBufferMetadata>()
+ .Build();
+ auto queue = ProducerQueue::Create(config, UsagePolicy{});
+ ASSERT_TRUE(queue != nullptr);
+
+ mProducer = BufferHubQueueProducer::Create(std::move(queue));
ASSERT_TRUE(mProducer != nullptr);
mSurface = new Surface(mProducer, true);
ASSERT_TRUE(mSurface != nullptr);
@@ -546,6 +555,55 @@
EXPECT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
}
+TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) {
+ // Connected producer cannot be taken out as a parcelable.
+ EXPECT_NO_FATAL_FAILURE(ConnectProducer());
+ ProducerQueueParcelable producer_parcelable;
+ EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE);
+
+ // Create a valid dummy producer parcelable.
+ auto dummy_channel_parcelable =
+ std::make_unique<pdx::default_transport::ChannelParcelable>(
+ LocalHandle(0), LocalHandle(0), LocalHandle(0));
+ EXPECT_TRUE(dummy_channel_parcelable->IsValid());
+ ProducerQueueParcelable dummy_producer_parcelable(
+ std::move(dummy_channel_parcelable));
+ EXPECT_TRUE(dummy_producer_parcelable.IsValid());
+
+ // Disconnect producer can be taken out, but only to an invalid parcelable.
+ ASSERT_EQ(mProducer->disconnect(kTestApi), NO_ERROR);
+ EXPECT_EQ(mProducer->TakeAsParcelable(&dummy_producer_parcelable), BAD_VALUE);
+ EXPECT_FALSE(producer_parcelable.IsValid());
+ EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), NO_ERROR);
+ EXPECT_TRUE(producer_parcelable.IsValid());
+
+ // Should still be able to query buffer dimension after disconnect.
+ int32_t value = -1;
+ EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
+ EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth);
+
+ EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), NO_ERROR);
+ EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight);
+
+ EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), NO_ERROR);
+ EXPECT_EQ(value, kDefaultFormat);
+
+ // But connect to API will fail.
+ IGraphicBufferProducer::QueueBufferOutput output;
+ EXPECT_EQ(mProducer->connect(kDummyListener, kTestApi, kTestControlledByApp,
+ &output),
+ BAD_VALUE);
+
+ // Create a new producer from the parcelable and connect to kTestApi should
+ // succeed.
+ sp<BufferHubQueueProducer> new_producer =
+ BufferHubQueueProducer::Create(std::move(producer_parcelable));
+ ASSERT_TRUE(new_producer != nullptr);
+ EXPECT_EQ(new_producer->connect(kDummyListener, kTestApi,
+ kTestControlledByApp, &output),
+ NO_ERROR);
+}
+
} // namespace
} // namespace dvr
diff --git a/opengl/tests/EGLTest/Android.bp b/opengl/tests/EGLTest/Android.bp
index d85af81..f246077 100644
--- a/opengl/tests/EGLTest/Android.bp
+++ b/opengl/tests/EGLTest/Android.bp
@@ -8,6 +8,11 @@
"EGL_test.cpp",
],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
shared_libs: [
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
diff --git a/opengl/tests/angeles/Android.bp b/opengl/tests/angeles/Android.bp
index bbbc447..5c398a6 100644
--- a/opengl/tests/angeles/Android.bp
+++ b/opengl/tests/angeles/Android.bp
@@ -8,6 +8,11 @@
"demo.c",
],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
gtest: false,
shared_libs: [
diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp
index ced8786..9d2c98f 100644
--- a/opengl/tests/angeles/app-linux.cpp
+++ b/opengl/tests/angeles/app-linux.cpp
@@ -62,9 +62,6 @@
int gAppAlive = 1;
-static const char sAppName[] =
- "San Angeles Observation OpenGL ES version example (Linux)";
-
static int sWindowWidth = WINDOW_DEFAULT_WIDTH;
static int sWindowHeight = WINDOW_DEFAULT_HEIGHT;
static EGLDisplay sEglDisplay = EGL_NO_DISPLAY;
@@ -132,7 +129,6 @@
EGLContext context;
EGLConfig config;
EGLSurface surface;
- EGLint w, h;
EGLDisplay dpy;
EGLNativeWindowType window = windowSurface.getSurface();
diff --git a/opengl/tests/configdump/Android.bp b/opengl/tests/configdump/Android.bp
index c46477c..ee967970 100644
--- a/opengl/tests/configdump/Android.bp
+++ b/opengl/tests/configdump/Android.bp
@@ -5,6 +5,11 @@
srcs: ["configdump.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
shared_libs: [
"libcutils",
"libEGL",
diff --git a/opengl/tests/fillrate/Android.bp b/opengl/tests/fillrate/Android.bp
index 543f1e3..689cee4 100644
--- a/opengl/tests/fillrate/Android.bp
+++ b/opengl/tests/fillrate/Android.bp
@@ -3,6 +3,11 @@
srcs: ["fillrate.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
gtest: false,
shared_libs: [
diff --git a/opengl/tests/fillrate/fillrate.cpp b/opengl/tests/fillrate/fillrate.cpp
index a42f3f2..f022069 100644
--- a/opengl/tests/fillrate/fillrate.cpp
+++ b/opengl/tests/fillrate/fillrate.cpp
@@ -153,7 +153,7 @@
for (int c=1, j=0 ; c<32 ; c++, j++) {
nsecs_t t = times[j];
- printf("%ld\t%d\t%f\n", t, c, (double(t)/c)/1000000.0);
+ printf("%lld\t%d\t%f\n", (long long)t, c, (double(t)/c)/1000000.0);
}
diff --git a/opengl/tests/filter/Android.bp b/opengl/tests/filter/Android.bp
index 5f925c8..23241e1 100644
--- a/opengl/tests/filter/Android.bp
+++ b/opengl/tests/filter/Android.bp
@@ -16,5 +16,10 @@
static_libs: ["libglTest"],
- cflags: ["-DGL_GLEXT_PROTOTYPES"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
+ ],
+
}
diff --git a/opengl/tests/filter/filter.cpp b/opengl/tests/filter/filter.cpp
index 287ee93..49778a0 100644
--- a/opengl/tests/filter/filter.cpp
+++ b/opengl/tests/filter/filter.cpp
@@ -140,6 +140,7 @@
//glDrawTexiOES(0, 0, 0, dim, dim);
+#if !USE_DRAW_TEXTURE || !GL_OES_draw_texture
const GLfloat fdim = dim;
const GLfloat vertices[4][2] = {
{ 0, 0 },
@@ -154,6 +155,7 @@
{ 1, 1 },
{ 1, 0 }
};
+#endif
if (!usePbuffer) {
eglSwapBuffers(dpy, surface);
diff --git a/opengl/tests/finish/Android.bp b/opengl/tests/finish/Android.bp
index fb5671d..be20851 100644
--- a/opengl/tests/finish/Android.bp
+++ b/opengl/tests/finish/Android.bp
@@ -16,5 +16,10 @@
static_libs: ["libglTest"],
- cflags: ["-DGL_GLEXT_PROTOTYPES"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
+ ],
+
}
diff --git a/opengl/tests/finish/finish.cpp b/opengl/tests/finish/finish.cpp
index ab955fe..63ea822 100644
--- a/opengl/tests/finish/finish.cpp
+++ b/opengl/tests/finish/finish.cpp
@@ -64,7 +64,6 @@
eglMakeCurrent(dpy, surface, surface, context);
eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
- GLint dim = w<h ? w : h;
glBindTexture(GL_TEXTURE_2D, 0);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
diff --git a/opengl/tests/gl2_basic/Android.bp b/opengl/tests/gl2_basic/Android.bp
index 7403271..f4538ad 100644
--- a/opengl/tests/gl2_basic/Android.bp
+++ b/opengl/tests/gl2_basic/Android.bp
@@ -16,5 +16,10 @@
static_libs: ["libglTest"],
- cflags: ["-DGL_GLEXT_PROTOTYPES"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
+ ],
+
}
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 67c0969..13f6fba 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -340,7 +340,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
diff --git a/opengl/tests/gl2_copyTexImage/Android.bp b/opengl/tests/gl2_copyTexImage/Android.bp
index 51e269c..87fa7ea 100644
--- a/opengl/tests/gl2_copyTexImage/Android.bp
+++ b/opengl/tests/gl2_copyTexImage/Android.bp
@@ -16,5 +16,9 @@
static_libs: ["libglTest"],
- cflags: ["-DGL_GLEXT_PROTOTYPES"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
+ ],
}
diff --git a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
index e0aafa2..ada98aa 100644
--- a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
+++ b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
@@ -444,7 +444,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
diff --git a/opengl/tests/gl2_yuvtex/Android.bp b/opengl/tests/gl2_yuvtex/Android.bp
index 613d678..b64d94d 100644
--- a/opengl/tests/gl2_yuvtex/Android.bp
+++ b/opengl/tests/gl2_yuvtex/Android.bp
@@ -20,5 +20,7 @@
cflags: [
"-DGL_GLEXT_PROTOTYPES",
"-DEGL_EGLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
],
}
diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
index 22128ab..850a615 100644
--- a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
+++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
@@ -190,7 +190,7 @@
static sp<GraphicBuffer> yuvTexBuffer;
static GLuint yuvTex;
-bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) {
+bool setupYuvTexSurface(EGLDisplay dpy, EGLContext /*context*/) {
int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1;
int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1;
yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat,
@@ -399,7 +399,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
diff --git a/opengl/tests/gl_basic/Android.bp b/opengl/tests/gl_basic/Android.bp
index 881d8ce..5eed17e 100644
--- a/opengl/tests/gl_basic/Android.bp
+++ b/opengl/tests/gl_basic/Android.bp
@@ -3,6 +3,11 @@
srcs: ["gl_basic.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
gtest: false,
shared_libs: [
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index 0b663f7..a675c7c 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -191,8 +191,6 @@
int main(int /*argc*/, char **/*argv*/)
{
- int q;
- int start, end;
printf("Initializing EGL...\n");
WindowSurface windowSurface;
if(!init_gl_surface(windowSurface))
@@ -212,7 +210,6 @@
int init_gl_surface(const WindowSurface& windowSurface)
{
- EGLint numConfigs = 1;
EGLConfig myConfig = {0};
EGLint attrib[] =
{
@@ -265,7 +262,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
@@ -336,9 +332,6 @@
void render()
{
- int i, j;
- int quads = 1;
-
const GLfloat vertices[] = {
-1, -1, 0,
1, -1, 0,
diff --git a/opengl/tests/gl_perf/Android.bp b/opengl/tests/gl_perf/Android.bp
index 0ffb121..25a317c 100644
--- a/opengl/tests/gl_perf/Android.bp
+++ b/opengl/tests/gl_perf/Android.bp
@@ -20,5 +20,9 @@
static_libs: ["libglTest"],
- cflags: ["-DGL_GLEXT_PROTOTYPES"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
+ ],
}
diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp
index 2998864..047db20 100644
--- a/opengl/tests/gl_perf/gl2_perf.cpp
+++ b/opengl/tests/gl_perf/gl2_perf.cpp
@@ -44,13 +44,6 @@
}
}
-static void checkGlError(const char* op) {
- for (GLint error = glGetError(); error; error
- = glGetError()) {
- fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
- }
-}
-
bool doTest(uint32_t w, uint32_t h);
static EGLDisplay dpy;
@@ -118,7 +111,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
glViewport(0, 0, w, h);
diff --git a/opengl/tests/gl_yuvtex/Android.bp b/opengl/tests/gl_yuvtex/Android.bp
index b6be327..9b4924a 100644
--- a/opengl/tests/gl_yuvtex/Android.bp
+++ b/opengl/tests/gl_yuvtex/Android.bp
@@ -19,5 +19,7 @@
cflags: [
"-DGL_GLEXT_PROTOTYPES",
"-DEGL_EGLEXT_PROTOTYPES",
+ "-Wall",
+ "-Werror",
],
}
diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
index 7ef3f4e..2c9640b 100644
--- a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
+++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
@@ -289,7 +289,6 @@
checkEglError("eglQuerySurface");
eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
checkEglError("eglQuerySurface");
- GLint dim = w < h ? w : h;
fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
diff --git a/opengl/tests/gralloc/Android.bp b/opengl/tests/gralloc/Android.bp
index 414c804..33c3dba 100644
--- a/opengl/tests/gralloc/Android.bp
+++ b/opengl/tests/gralloc/Android.bp
@@ -3,6 +3,11 @@
srcs: ["gralloc.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
gtest: false,
shared_libs: [
diff --git a/opengl/tests/linetex/Android.mk b/opengl/tests/linetex/Android.mk
index 968756a..3df0a0f 100644
--- a/opengl/tests/linetex/Android.mk
+++ b/opengl/tests/linetex/Android.mk
@@ -4,6 +4,8 @@
LOCAL_SRC_FILES:= \
linetex.cpp
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libEGL \
diff --git a/opengl/tests/swapinterval/Android.mk b/opengl/tests/swapinterval/Android.mk
index b0b15eb..2a2c12f 100644
--- a/opengl/tests/swapinterval/Android.mk
+++ b/opengl/tests/swapinterval/Android.mk
@@ -4,6 +4,8 @@
LOCAL_SRC_FILES:= \
swapinterval.cpp
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
diff --git a/opengl/tests/textures/Android.mk b/opengl/tests/textures/Android.mk
index bee61f9..629a2d2 100644
--- a/opengl/tests/textures/Android.mk
+++ b/opengl/tests/textures/Android.mk
@@ -21,5 +21,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES
+LOCAL_CFLAGS += -Wall -Werror
include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/textures/textures.cpp b/opengl/tests/textures/textures.cpp
index 7be942a..bdb5c82 100644
--- a/opengl/tests/textures/textures.cpp
+++ b/opengl/tests/textures/textures.cpp
@@ -87,12 +87,6 @@
0x0000, 0x5555, 0x0000, 0x5555,
0xAAAA, 0xFFFF, 0xAAAA, 0xFFFF };
- uint16_t t5551[] = {
- 0x0000, 0xFFFF, 0x0000, 0xFFFF,
- 0xFFFF, 0x0000, 0xFFFF, 0x0000,
- 0x0000, 0xFFFF, 0x0000, 0xFFFF,
- 0xFFFF, 0x0000, 0xFFFF, 0x0000 };
-
uint32_t t32[] = {
0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFFFF0000,
0xFF00FF00, 0xFFFF0000, 0xFF000000, 0xFF0000FF,
diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk
index 64382ed..7055afa 100644
--- a/opengl/tests/tritex/Android.mk
+++ b/opengl/tests/tritex/Android.mk
@@ -4,6 +4,8 @@
LOCAL_SRC_FILES:= \
tritex.cpp
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libEGL \
diff --git a/opengl/tests/tritex/tritex.cpp b/opengl/tests/tritex/tritex.cpp
index 2db73ef..c008003 100644
--- a/opengl/tests/tritex/tritex.cpp
+++ b/opengl/tests/tritex/tritex.cpp
@@ -93,9 +93,6 @@
int main(int argc, char **argv)
{
- int q;
- int start, end;
-
printf("Initializing EGL...\n");
WindowSurface windowSurface;
@@ -120,7 +117,6 @@
int init_gl_surface(const WindowSurface& windowSurface)
{
- EGLint numConfigs = 1;
EGLConfig myConfig = {0};
EGLint attrib[] =
{
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 0c1693b..c477a3b 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -613,14 +613,6 @@
return;
}
- // Client layers
- if (hwcInfo.forceClientComposition ||
- (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
- ALOGV("[%s] Requesting Client composition", mName.string());
- setCompositionType(hwcId, HWC2::Composition::Client);
- return;
- }
-
// Device or Cursor layers
if (mPotentialCursor) {
ALOGV("[%s] Requesting Cursor composition", mName.string());
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f5fb109..5b40aea 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -621,6 +621,15 @@
mHwcLayers[hwcId].forceClientComposition = true;
}
+bool Layer::getForceClientComposition(int32_t hwcId) {
+ if (mHwcLayers.count(hwcId) == 0) {
+ ALOGE("getForceClientComposition: no HWC layer found (%d)", hwcId);
+ return false;
+ }
+
+ return mHwcLayers[hwcId].forceClientComposition;
+}
+
void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
auto hwcId = displayDevice->getHwcDisplayId();
if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c125a3c..0fc5ad5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -299,6 +299,7 @@
void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z);
void forceClientComposition(int32_t hwcId);
+ bool getForceClientComposition(int32_t hwcId);
virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
// callIntoHwc exists so we can update our local state and call
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index d0f8fbe..47156c1 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -37,8 +37,8 @@
if (ls != rs)
return (ls > rs) ? 1 : -1;
- uint32_t lz = l->getCurrentState().z;
- uint32_t rz = r->getCurrentState().z;
+ int32_t lz = l->getCurrentState().z;
+ int32_t rz = r->getCurrentState().z;
if (lz != rz)
return (lz > rz) ? 1 : -1;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9e7563c..5e1de75 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1956,6 +1956,12 @@
"display %zd: %d", displayId, result);
}
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+ if (layer->getForceClientComposition(hwcId)) {
+ ALOGV("[%s] Requesting Client composition", layer->getName().string());
+ layer->setCompositionType(hwcId, HWC2::Composition::Client);
+ continue;
+ }
+
layer->setPerFrameData(displayDevice);
}
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index e6f2ce7..bf37e1e 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -29,9 +29,11 @@
uint32_t rs = rhs->layerStack;
if (ls != rs) return ls < rs;
- uint32_t lz = lhs->z;
- uint32_t rz = rhs->z;
- if (lz != rz) return lz < rz;
+ int32_t lz = lhs->z;
+ int32_t rz = rhs->z;
+ if (lz != rz) {
+ return (lz > rz) ? 1 : -1;
+ }
return lhs->id < rhs->id;
}