Merge "Build libfakeservicemanager for host."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 544e26c..8637a31 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -233,6 +233,7 @@
{ REQ, "events/filemap/enable" },
} },
{ "memory", "Memory", 0, {
+ { OPT, "events/mm_event/mm_event_record/enable" },
{ OPT, "events/kmem/rss_stat/enable" },
{ OPT, "events/kmem/ion_heap_grow/enable" },
{ OPT, "events/kmem/ion_heap_shrink/enable" },
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 6e460a0..040ddde 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -107,6 +107,8 @@
chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_grow/enable
chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_heap_shrink/enable
chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_shrink/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/mm_event/mm_event_record/enable
+ chmod 0666 /sys/kernel/tracing/events/mm_event/mm_event_record/enable
chmod 0666 /sys/kernel/debug/tracing/events/signal/signal_generate/enable
chmod 0666 /sys/kernel/tracing/events/signal/signal_generate/enable
chmod 0666 /sys/kernel/debug/tracing/events/signal/signal_deliver/enable
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 310b5ce..f535605 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1437,6 +1437,8 @@
ds.AddDir(WMTRACE_DATA_DIR, false);
}
+ ds.AddDir(SNAPSHOTCTL_LOG_DIR, false);
+
RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(ds.DumpstateBoard);
/* Migrate the ril_dumpstate to a device specific dumpstate? */
@@ -1569,7 +1571,6 @@
ds.AddDir(RECOVERY_DATA_DIR, true);
ds.AddDir(UPDATE_ENGINE_LOG_DIR, true);
ds.AddDir(LOGPERSIST_DATA_DIR, false);
- ds.AddDir(SNAPSHOTCTL_LOG_DIR, false);
if (!PropertiesHelper::IsUserBuild()) {
ds.AddDir(PROFILE_DATA_DIR_CUR, true);
ds.AddDir(PROFILE_DATA_DIR_REF, true);
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index a427c8d..1327cfd 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -230,7 +230,7 @@
}
const size_t N = services.size();
- if (N > 1) {
+ if (N > 1 || showListOnly) {
// first print a list of the current services
std::cout << "Currently running services:" << std::endl;
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index b9395ba..3467898 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -206,10 +206,7 @@
}
void AssertRunningServices(const std::vector<std::string>& services) {
- std::string expected;
- if (services.size() > 1) {
- expected.append("Currently running services:\n");
- }
+ std::string expected = "Currently running services:\n";
for (const std::string& service : services) {
expected.append(" ").append(service).append("\n");
}
@@ -263,6 +260,21 @@
AssertRunningServices({"Locksmith", "Valet"});
}
+TEST_F(DumpsysTest, ListServicesOneRegistered) {
+ ExpectListServices({"Locksmith"});
+ ExpectCheckService("Locksmith");
+
+ CallMain({"-l"});
+
+ AssertRunningServices({"Locksmith"});
+}
+
+TEST_F(DumpsysTest, ListServicesEmpty) {
+ CallMain({"-l"});
+
+ AssertRunningServices({});
+}
+
// Tests 'dumpsys -l' when a service is not running
TEST_F(DumpsysTest, ListRunningServices) {
ExpectListServices({"Locksmith", "Valet"});
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index dc0583e..6fee11b 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -42,6 +42,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
@@ -74,6 +75,7 @@
#define LOG_TAG "installd"
#endif
+using android::base::ParseUint;
using android::base::StringPrintf;
using std::endl;
@@ -1090,6 +1092,43 @@
return ok();
}
+binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified(
+ const std::optional<std::string> &volumeUuid, const int32_t user,
+ const std::vector<int32_t>& retainSnapshotIds) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+
+ const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
+
+ auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, user);
+
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(base_path.c_str()), closedir);
+ if (!dir) {
+ return error(-1, "Failed to open rollback base dir " + base_path);
+ }
+
+ struct dirent* ent;
+ while ((ent = readdir(dir.get()))) {
+ if (ent->d_type != DT_DIR) {
+ continue;
+ }
+
+ uint snapshot_id;
+ bool parse_ok = ParseUint(ent->d_name, &snapshot_id);
+ if (parse_ok &&
+ std::find(retainSnapshotIds.begin(), retainSnapshotIds.end(),
+ snapshot_id) == retainSnapshotIds.end()) {
+ auto rollback_path = create_data_misc_ce_rollback_path(
+ volume_uuid, user, snapshot_id);
+ int res = delete_dir_contents_and_dir(rollback_path, true /* ignore_if_missing */);
+ if (res != 0) {
+ return error(res, "Failed clearing snapshot " + rollback_path);
+ }
+ }
+ }
+ return ok();
+}
binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::string>& fromUuid,
const std::optional<std::string>& toUuid, const std::string& packageName,
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 80a88b4..1a8da5f 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -69,6 +69,8 @@
binder::Status destroyAppDataSnapshot(const std::optional<std::string> &volumeUuid,
const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode,
const int32_t snapshotId, int32_t storageFlags);
+ binder::Status destroyCeSnapshotsNotSpecified(const std::optional<std::string> &volumeUuid,
+ const int32_t user, const std::vector<int32_t>& retainSnapshotIds);
binder::Status getAppSize(const std::optional<std::string>& uuid,
const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index d99bcc8..0b9a444 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -109,6 +109,8 @@
int userId, int snapshotId, int storageFlags);
void restoreAppDataSnapshot(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName,
int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags);
+ void destroyCeSnapshotsNotSpecified(@nullable @utf8InCpp String uuid, int userId,
+ in int[] retainSnapshotIds);
void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
int userId, long ceSnapshotInode, int snapshotId, int storageFlags);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index ebb8f0f..5e87faf 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1273,11 +1273,6 @@
Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path,
bool generate_app_image, bool is_public, int uid, bool is_secondary_dex) {
- // We don't create an image for secondary dex files.
- if (is_secondary_dex) {
- return Dex2oatFileWrapper();
- }
-
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.
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index eefbe4f..d773790 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -138,10 +138,10 @@
return 4;
}
- PrepareEnvironment();
+ PrepareEnvironmentVariables();
- if (!PrepareBootImage(/* force */ false)) {
- LOG(ERROR) << "Failed preparing boot image.";
+ if (!EnsureBootImageAndDalvikCache()) {
+ LOG(ERROR) << "Bad boot image.";
return 5;
}
@@ -302,7 +302,7 @@
return parameters_.ReadArguments(argc, const_cast<const char**>(argv));
}
- void PrepareEnvironment() {
+ void PrepareEnvironmentVariables() {
environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str()));
environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str()));
environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str()));
@@ -312,9 +312,8 @@
}
}
- // Ensure that we have the right boot image. The first time any app is
- // compiled, we'll try to generate it.
- bool PrepareBootImage(bool force) const {
+ // Ensure that we have the right boot image and cache file structures.
+ bool EnsureBootImageAndDalvikCache() const {
if (parameters_.instruction_set == nullptr) {
LOG(ERROR) << "Instruction set missing.";
return false;
@@ -340,34 +339,19 @@
}
}
- // Check whether we have files in /data.
+ // Clear cached artifacts.
+ ClearDirectory(isa_path);
+
+ // Check whether we have a boot image.
// TODO: check that the files are correct wrt/ jars.
- std::string art_path = isa_path + "/system@framework@boot.art";
- std::string oat_path = isa_path + "/system@framework@boot.oat";
- bool cleared = false;
- if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
- // Files exist, assume everything is alright if not forced. Otherwise clean up.
- if (!force) {
- return true;
- }
- ClearDirectory(isa_path);
- cleared = true;
+ std::string preopted_boot_art_path =
+ StringPrintf("/apex/com.android.art/javalib/%s/boot.art", isa);
+ if (access(preopted_boot_art_path.c_str(), F_OK) != 0) {
+ PLOG(ERROR) << "Bad access() to " << preopted_boot_art_path;
+ return false;
}
- // Check whether we have an image in /system.
- // TODO: check that the files are correct wrt/ jars.
- std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
- if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
- // Note: we ignore |force| here.
- return true;
- }
-
-
- if (!cleared) {
- ClearDirectory(isa_path);
- }
-
- return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
+ return true;
}
static bool CreatePath(const std::string& path) {
@@ -432,77 +416,6 @@
CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
}
- bool Dex2oatBootImage(const std::string& boot_cp,
- const std::string& art_path,
- const std::string& oat_path,
- const char* isa) const {
- // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
- std::vector<std::string> cmd;
- cmd.push_back(kDex2oatPath);
- cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
- for (const std::string& boot_part : Split(boot_cp, ":")) {
- cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
- }
- cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str()));
-
- int32_t base_offset = ChooseRelocationOffsetDelta(
- art::imagevalues::GetImageMinBaseAddressDelta(),
- art::imagevalues::GetImageMaxBaseAddressDelta());
- cmd.push_back(StringPrintf("--base=0x%x",
- art::imagevalues::GetImageBaseAddress() + base_offset));
-
- cmd.push_back(StringPrintf("--instruction-set=%s", isa));
-
- // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp.
- AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms",
- "-Xms",
- true,
- cmd);
- AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx",
- "-Xmx",
- true,
- cmd);
- AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter",
- "--compiler-filter=",
- false,
- cmd);
- cmd.push_back("--profile-file=/system/etc/boot-image.prof");
- // TODO: Compiled-classes.
- const std::string* extra_opts =
- system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
- if (extra_opts != nullptr) {
- std::vector<std::string> extra_vals = Split(*extra_opts, " ");
- cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end());
- }
- // TODO: Should we lower this? It's usually set close to max, because
- // normally there's not much else going on at boot.
- AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads",
- "-j",
- false,
- cmd);
- AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-cpu-set",
- "--cpu-set=",
- false,
- cmd);
- AddCompilerOptionFromSystemProperty(
- StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(),
- "--instruction-set-variant=",
- false,
- cmd);
- AddCompilerOptionFromSystemProperty(
- StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(),
- "--instruction-set-features=",
- false,
- cmd);
-
- std::string error_msg;
- bool result = Exec(cmd, &error_msg);
- if (!result) {
- LOG(ERROR) << "Could not generate boot image: " << error_msg;
- }
- return result;
- }
-
static const char* ParseNull(const char* arg) {
return (strcmp(arg, "!") == 0) ? nullptr : arg;
}
@@ -592,22 +505,6 @@
return 0;
}
- // If the dexopt failed, we may have a stale boot image from a previous OTA run.
- // Then regenerate and retry.
- if (WEXITSTATUS(dexopt_result) ==
- static_cast<int>(::art::dex2oat::ReturnCode::kCreateRuntime)) {
- if (!PrepareBootImage(/* force */ true)) {
- LOG(ERROR) << "Forced boot image creating failed. Original error return was "
- << dexopt_result;
- return dexopt_result;
- }
-
- int dexopt_result_boot_image_retry = Dexopt();
- if (dexopt_result_boot_image_retry == 0) {
- return 0;
- }
- }
-
// If this was a profile-guided run, we may have profile version issues. Try to downgrade,
// if possible.
if ((parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) {
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 7278677..1e7559d 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -640,6 +640,46 @@
"com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
}
+TEST_F(AppDataSnapshotTest, DestroyCeSnapshotsNotSpecified) {
+ auto rollback_ce_dir_in_1 = create_data_misc_ce_rollback_path("TEST", 0, 1543);
+ auto rollback_ce_dir_in_2 = create_data_misc_ce_rollback_path("TEST", 0, 77);
+ auto rollback_ce_dir_out_1 = create_data_misc_ce_rollback_path("TEST", 0, 1500);
+ auto rollback_ce_dir_out_2 = create_data_misc_ce_rollback_path("TEST", 0, 2);
+
+ // Create snapshots
+ ASSERT_TRUE(mkdirs(rollback_ce_dir_in_1 + "/com.foo/", 0700));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "CE_RESTORE_CONTENT", rollback_ce_dir_in_1 + "/com.foo/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ ASSERT_TRUE(mkdirs(rollback_ce_dir_in_2 + "/com.foo/", 0700));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "CE_RESTORE_CONTENT", rollback_ce_dir_in_2 + "/com.foo/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ ASSERT_TRUE(mkdirs(rollback_ce_dir_out_1 + "/com.foo/", 0700));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "CE_RESTORE_CONTENT", rollback_ce_dir_out_1 + "/com.foo/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ ASSERT_TRUE(mkdirs(rollback_ce_dir_out_2 + "/com.foo/", 0700));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "CE_RESTORE_CONTENT", rollback_ce_dir_out_2 + "/com.foo/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ ASSERT_TRUE(service->destroyCeSnapshotsNotSpecified(
+ std::make_optional<std::string>("TEST"), 0, { 1543, 77 }).isOk());
+
+ // Check only snapshots not specified are deleted.
+ struct stat sb;
+ ASSERT_EQ(0, stat((rollback_ce_dir_in_1 + "/com.foo").c_str(), &sb));
+ ASSERT_EQ(0, stat((rollback_ce_dir_in_2 + "/com.foo").c_str(), &sb));
+ ASSERT_EQ(-1, stat((rollback_ce_dir_out_1 + "/com.foo").c_str(), &sb));
+ ASSERT_EQ(ENOENT, errno);
+ ASSERT_EQ(-1, stat((rollback_ce_dir_out_2 + "/com.foo").c_str(), &sb));
+ ASSERT_EQ(ENOENT, errno);
+}
+
TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
// Setup rollback data to make sure that fails due to wrong volumeUuid being
// passed, not because of some other reason.
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index f426dbb..fb11cee 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -406,7 +406,7 @@
return false;
}
- if (fqInstance.getPackage() == gIBaseFqName.package()) {
+ if (fqInstance.getPackage() == "android.hidl.base") {
return true; // always remove IBase from manifest
}
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index abe6436..cbbea12 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -522,6 +522,11 @@
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
+ if (serviceIt->second.guaranteeClient) {
+ LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ }
+
int clients = handleServiceClientCallback(name, false);
// clients < 0: feature not implemented or other error. Assume clients.
@@ -532,6 +537,8 @@
if (clients < 0 || clients > 2) {
// client callbacks are either disabled or there are other clients
LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
+ // Set this flag to ensure the clients are acknowledged in the next callback
+ serviceIt->second.guaranteeClient = true;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index 4365a3c..d23e3b7 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -37,7 +37,6 @@
virtual void setInputWindows(const std::vector<InputWindowInfo>& inputHandles,
const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0;
- virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;
};
@@ -51,8 +50,7 @@
enum {
SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
REGISTER_INPUT_CHANNEL_TRANSACTION,
- UNREGISTER_INPUT_CHANNEL_TRANSACTION,
- TRANSFER_TOUCH_FOCUS
+ UNREGISTER_INPUT_CHANNEL_TRANSACTION
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index bc541f4..6023f92 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -73,9 +73,9 @@
// or dessert updates. Instead, apex users should use libbinder_ndk.
apex_available: [
"//apex_available:platform",
- // TODO(b/139016109) remove these three
+ // TODO(b/139016109) remove these
+ "com.android.media",
"com.android.media.swcodec",
- "test_com.android.media.swcodec",
],
srcs: [
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 2f6e9c3..e0fb543 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -141,7 +141,7 @@
// ---------------------------------------------------------------------------
-BBinder::BBinder() : mExtras(nullptr)
+BBinder::BBinder() : mExtras(nullptr), mStability(0)
{
}
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index f16c39c..d2b9b8f 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -138,6 +138,7 @@
BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
: mHandle(handle)
+ , mStability(0)
, mAlive(1)
, mObitsSent(0)
, mObituaries(nullptr)
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 71d8130..74aece8 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -31,11 +31,16 @@
class ClientCounterCallback : public ::android::os::BnClientCallback {
public:
- ClientCounterCallback() : mNumConnectedServices(0) {}
+ ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {}
bool registerService(const sp<IBinder>& service, const std::string& name,
bool allowIsolated, int dumpFlags);
+ /**
+ * Set a flag to prevent services from automatically shutting down
+ */
+ void forcePersist(bool persist);
+
protected:
Status onClients(const sp<IBinder>& service, bool clients) override;
@@ -60,6 +65,8 @@
* Map of registered names and services
*/
std::map<std::string, Service> mRegisteredServices;
+
+ bool mForcePersist;
};
bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
@@ -88,6 +95,14 @@
return true;
}
+void ClientCounterCallback::forcePersist(bool persist) {
+ mForcePersist = persist;
+ if(!mForcePersist) {
+ // Attempt a shutdown in case the number of clients hit 0 while the flag was on
+ tryShutdown();
+ }
+}
+
/**
* onClients is oneway, so no need to worry about multi-threading. Note that this means multiple
* invocations could occur on different threads however.
@@ -103,14 +118,21 @@
mNumConnectedServices, mRegisteredServices.size(),
String8(service->getInterfaceDescriptor()).string(), clients);
- if (mNumConnectedServices == 0) {
- tryShutdown();
- }
-
+ tryShutdown();
return Status::ok();
}
void ClientCounterCallback::tryShutdown() {
+ if(mNumConnectedServices > 0) {
+ // Should only shut down if there are no clients
+ return;
+ }
+
+ if(mForcePersist) {
+ ALOGI("Shutdown prevented by forcePersist override flag.");
+ return;
+ }
+
ALOGI("Trying to shut down the service. No clients in use for any service in process.");
auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
@@ -165,5 +187,9 @@
return OK;
}
+void LazyServiceRegistrar::forcePersist(bool persist) {
+ mClientCC->forcePersist(persist);
+}
+
} // namespace hardware
} // namespace android
\ No newline at end of file
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 631e8c5..0f81e0b 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -328,6 +328,8 @@
}
status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) {
+ LOG_ALWAYS_FATAL_IF(mThreadPoolStarted && maxThreads < mMaxThreads,
+ "Binder threadpool cannot be shrunk after starting");
status_t result = NO_ERROR;
if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) != -1) {
mMaxThreads = maxThreads;
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 7ce5e36..e1565fa 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -15,6 +15,9 @@
*/
#include <binder/Stability.h>
+#include <binder/BpBinder.h>
+#include <binder/Binder.h>
+
namespace android {
namespace internal {
@@ -78,11 +81,12 @@
if (currentStability == stability) return OK;
- binder->attachObject(
- reinterpret_cast<void*>(&Stability::get),
- reinterpret_cast<void*>(stability),
- nullptr /*cleanupCookie*/,
- nullptr /*cleanup function*/);
+ BBinder* local = binder->localBinder();
+ if (local != nullptr) {
+ local->mStability = static_cast<int32_t>(stability);
+ } else {
+ binder->remoteBinder()->mStability = static_cast<int32_t>(stability);
+ }
return OK;
}
@@ -90,8 +94,12 @@
Stability::Level Stability::get(IBinder* binder) {
if (binder == nullptr) return UNDECLARED;
- return static_cast<Level>(reinterpret_cast<intptr_t>(
- binder->findObject(reinterpret_cast<void*>(&Stability::get))));
+ BBinder* local = binder->localBinder();
+ if (local != nullptr) {
+ return static_cast<Stability::Level>(local->mStability);
+ }
+
+ return static_cast<Stability::Level>(binder->remoteBinder()->mStability);
}
bool Stability::check(int32_t provided, Level required) {
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 3be61f9..74e52db 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -24,6 +24,10 @@
// ---------------------------------------------------------------------------
namespace android {
+namespace internal {
+class Stability;
+}
+
class BBinder : public IBinder
{
public:
@@ -88,7 +92,12 @@
Extras* getOrCreateExtras();
std::atomic<Extras*> mExtras;
- void* mReserved0;
+
+ friend ::android::internal::Stability;
+ union {
+ int32_t mStability;
+ void* mReserved0;
+ };
};
// ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 7dca733..378a911 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -27,6 +27,10 @@
// ---------------------------------------------------------------------------
namespace android {
+namespace internal {
+class Stability;
+};
+
using binder_proxy_limit_callback = void(*)(int);
class BpBinder : public IBinder
@@ -116,6 +120,9 @@
private:
const int32_t mHandle;
+ friend ::android::internal::Stability;
+ int32_t mStability;
+
struct Obituary {
wp<DeathRecipient> recipient;
void* cookie;
@@ -130,7 +137,6 @@
volatile int32_t mObitsSent;
Vector<Obituary>* mObituaries;
ObjectManager mObjects;
- Parcel* mConstantData;
mutable String16 mDescriptorCache;
int32_t mTrackedUid;
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 64604b7..eea0e89 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -173,6 +173,10 @@
* The @a cookie is optional -- if non-NULL, it should be a
* memory address that you own (that is, you know it is unique).
*
+ * @note When all references to the binder being linked to are dropped, the
+ * recipient is automatically unlinked. So, you must hold onto a binder in
+ * order to receive death notifications about it.
+ *
* @note You will only receive death notifications for remote binders,
* as local binders by definition can't die without you dying as well.
* Trying to use this function on a local binder will result in an
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 4818889..b4e4a42 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -39,12 +39,28 @@
status_t clearLastError();
+ /**
+ * Returns the PID of the process which has made the current binder
+ * call. If not in a binder call, this will return getpid. If the
+ * call is oneway, this will return 0.
+ */
pid_t getCallingPid() const;
- // nullptr if unavailable
- //
- // this can't be restored once it's cleared, and it does not return the
- // context of the current process when not in a binder call.
+
+ /**
+ * Returns the SELinux security identifier of the process which has
+ * made the current binder call. If not in a binder call this will
+ * return nullptr. If this isn't requested with
+ * IBinder::setRequestingSid, it will also return nullptr.
+ *
+ * This can't be restored once it's cleared, and it does not return the
+ * context of the current process when not in a binder call.
+ */
const char* getCallingSid() const;
+
+ /**
+ * Returns the UID of the process which has made the current binder
+ * call. If not in a binder call, this will return 0.
+ */
uid_t getCallingUid() const;
void setStrictModePolicy(int32_t policy);
diff --git a/libs/binder/include/binder/LazyServiceRegistrar.h b/libs/binder/include/binder/LazyServiceRegistrar.h
index efdecc4..6d711bc 100644
--- a/libs/binder/include/binder/LazyServiceRegistrar.h
+++ b/libs/binder/include/binder/LazyServiceRegistrar.h
@@ -34,6 +34,12 @@
const std::string& name = "default",
bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+ /**
+ * Force the service to persist, even when it has 0 clients.
+ * If setting this flag from the server side, make sure to do so before calling registerService,
+ * or there may be a race with the default dynamic shutdown.
+ */
+ void forcePersist(bool persist);
private:
std::shared_ptr<internal::ClientCounterCallback> mClientCC;
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 75dcdc8..649faa1 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -486,7 +486,6 @@
void AIBinder_incStrong(AIBinder* binder) {
if (binder == nullptr) {
- LOG(ERROR) << __func__ << ": on null binder";
return;
}
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index df5df13..09949ea 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -831,34 +831,34 @@
}
/**
- * Writes a vector of int8_t to the next location in a non-null parcel.
+ * Writes a vector of uint8_t to the next location in a non-null parcel.
*/
-inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int8_t>& vec) {
- return AParcel_writeByteArray(parcel, vec.data(), vec.size());
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint8_t>& vec) {
+ return AParcel_writeByteArray(parcel, reinterpret_cast<const int8_t*>(vec.data()), vec.size());
}
/**
- * Writes an optional vector of int8_t to the next location in a non-null parcel.
+ * Writes an optional vector of uint8_t to the next location in a non-null parcel.
*/
inline binder_status_t AParcel_writeVector(AParcel* parcel,
- const std::optional<std::vector<int8_t>>& vec) {
+ const std::optional<std::vector<uint8_t>>& vec) {
if (!vec) return AParcel_writeByteArray(parcel, nullptr, -1);
return AParcel_writeVector(parcel, *vec);
}
/**
- * Reads a vector of int8_t from the next location in a non-null parcel.
+ * Reads a vector of uint8_t from the next location in a non-null parcel.
*/
-inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint8_t>* vec) {
void* vectorData = static_cast<void*>(vec);
return AParcel_readByteArray(parcel, vectorData, AParcel_stdVectorAllocator<int8_t>);
}
/**
- * Reads an optional vector of int8_t from the next location in a non-null parcel.
+ * Reads an optional vector of uint8_t from the next location in a non-null parcel.
*/
inline binder_status_t AParcel_readVector(const AParcel* parcel,
- std::optional<std::vector<int8_t>>* vec) {
+ std::optional<std::vector<uint8_t>>* vec) {
void* vectorData = static_cast<void*>(vec);
return AParcel_readByteArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<int8_t>);
}
diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp
index c186110..9e50729 100644
--- a/libs/binderthreadstate/Android.bp
+++ b/libs/binderthreadstate/Android.bp
@@ -20,6 +20,10 @@
vendor_available: true,
host_supported: true,
+ apex_available: [
+ "com.android.media",
+ ],
+
shared_libs: [
"libbinder",
"libhidlbase", // libhwbinder is in here
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 0ede8b1..32baa5f 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -56,6 +56,9 @@
"android.hardware.audio@4.0::IDevicesFactory",
"android.hardware.audio@5.0::IDevicesFactory",
"android.hardware.audio@6.0::IDevicesFactory",
+ "android.hardware.automotive.audiocontrol@1.0::IAudioControl",
+ "android.hardware.automotive.evs@1.0::IEvsCamera",
+ "android.hardware.automotive.vehicle@2.0::IVehicle",
"android.hardware.biometrics.face@1.0::IBiometricsFace",
"android.hardware.bluetooth@1.0::IBluetoothHci",
"android.hardware.camera.provider@2.4::ICameraProvider",
@@ -66,6 +69,7 @@
"android.hardware.media.c2@1.0::IComponentStore",
"android.hardware.media.omx@1.0::IOmx",
"android.hardware.media.omx@1.0::IOmxStore",
+ "android.hardware.neuralnetworks@1.0::IDevice",
"android.hardware.power@1.3::IPower",
"android.hardware.power.stats@1.0::IPowerStats",
"android.hardware.sensors@1.0::ISensors",
diff --git a/libs/gralloc/OWNERS b/libs/gralloc/OWNERS
index 67743cd..4a95778 100644
--- a/libs/gralloc/OWNERS
+++ b/libs/gralloc/OWNERS
@@ -1,2 +1,2 @@
-marissaw@google.com
+chrisforbes@google.com
vhau@google.com
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 528bfb1..3a7cb44 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -166,7 +166,9 @@
mCore->mFreeBuffers.push_back(front->mSlot);
}
- listener = mCore->mConnectedProducerListener;
+ if (mCore->mBufferReleasedCbEnabled) {
+ listener = mCore->mConnectedProducerListener;
+ }
++numDroppedBuffers;
}
@@ -457,7 +459,9 @@
mCore->mFreeBuffers.push_back(slot);
}
- listener = mCore->mConnectedProducerListener;
+ if (mCore->mBufferReleasedCbEnabled) {
+ listener = mCore->mConnectedProducerListener;
+ }
BQ_LOGV("releaseBuffer: releasing slot %d", slot);
mCore->mDequeueCondition.notify_all();
@@ -668,7 +672,7 @@
BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
VALIDATE_CONSISTENCY();
- if (delta < 0) {
+ if (delta < 0 && mCore->mBufferReleasedCbEnabled) {
listener = mCore->mConsumerListener;
}
}
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index e0e3431..0264bd2 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -65,6 +65,7 @@
mConnectedApi(NO_CONNECTED_API),
mLinkedToDeath(),
mConnectedProducerListener(),
+ mBufferReleasedCbEnabled(false),
mSlots(),
mQueue(),
mFreeSlots(),
@@ -260,6 +261,12 @@
}
void BufferQueueCore::discardFreeBuffersLocked() {
+ // Notify producer about the discarded buffers.
+ if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) {
+ std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end());
+ mConnectedProducerListener->onBuffersDiscarded(freeBuffers);
+ }
+
for (int s : mFreeBuffers) {
mFreeSlots.insert(s);
clearBufferSlotLocked(s);
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 3efb1b6..4f8eb6b 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1221,9 +1221,8 @@
}
mCore->mLinkedToDeath = listener;
}
- if (listener->needsReleaseNotify()) {
- mCore->mConnectedProducerListener = listener;
- }
+ mCore->mConnectedProducerListener = listener;
+ mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify();
}
break;
default:
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 936063a..808e336 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -24,6 +24,7 @@
enum {
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
NEEDS_RELEASE_NOTIFY,
+ ON_BUFFERS_DISCARDED,
};
class BpProducerListener : public BpInterface<IProducerListener>
@@ -56,6 +57,13 @@
}
return result;
}
+
+ virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+ data.writeInt32Vector(discardedSlots);
+ remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -76,6 +84,10 @@
virtual bool needsReleaseNotify() override {
return mBase->needsReleaseNotify();
}
+
+ virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override {
+ return mBase->onBuffersDiscarded(discardedSlots);
+ }
};
IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener,
@@ -92,6 +104,17 @@
CHECK_INTERFACE(IProducerListener, data, reply);
reply->writeBool(needsReleaseNotify());
return NO_ERROR;
+ case ON_BUFFERS_DISCARDED: {
+ CHECK_INTERFACE(IProducerListener, data, reply);
+ std::vector<int32_t> discardedSlots;
+ status_t result = data.readInt32Vector(&discardedSlots);
+ if (result != NO_ERROR) {
+ ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result);
+ return result;
+ }
+ onBuffersDiscarded(discardedSlots);
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
@@ -104,4 +127,7 @@
return true;
}
+void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) {
+}
+
} // namespace android
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index c13401d..b77dfda 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -1,10 +1,9 @@
adyabr@google.com
akrulec@google.com
alecmouri@google.com
+chrisforbes@google.com
jessehall@google.com
-jwcai@google.com
lpy@google.com
-marissaw@google.com
mathias@google.com
racarr@google.com
steventhomas@google.com
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 9fe5de8..b822319 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -35,6 +35,7 @@
#include <ui/DisplayStatInfo.h>
#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
@@ -1287,6 +1288,14 @@
}
int Surface::connect(
+ int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) {
+ if (sListener != nullptr) {
+ mListenerProxy = new ProducerListenerProxy(this, sListener);
+ }
+ return connect(api, mListenerProxy, reportBufferRemoval);
+}
+
+int Surface::connect(
int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
ATRACE_CALL();
ALOGV("Surface::connect");
@@ -1684,6 +1693,28 @@
}
}
+status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots,
+ std::vector<sp<GraphicBuffer>>* outBuffers) {
+ ALOGV("Surface::getAndFlushBuffersFromSlots");
+ for (int32_t i : slots) {
+ if (i < 0 || i >= NUM_BUFFER_SLOTS) {
+ ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i);
+ return BAD_VALUE;
+ }
+ }
+
+ Mutex::Autolock lock(mMutex);
+ for (int32_t i : slots) {
+ if (mSlots[i].buffer == nullptr) {
+ ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i);
+ continue;
+ }
+ outBuffers->push_back(mSlots[i].buffer);
+ mSlots[i].buffer = nullptr;
+ }
+ return OK;
+}
+
void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
ATRACE_CALL();
ALOGV("Surface::setSurfaceDamage");
@@ -1951,4 +1982,22 @@
return err;
}
+void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) {
+ ATRACE_CALL();
+ sp<Surface> parent = mParent.promote();
+ if (parent == nullptr) {
+ return;
+ }
+
+ std::vector<sp<GraphicBuffer>> discardedBufs;
+ status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs);
+ if (res != OK) {
+ ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__,
+ strerror(-res), res);
+ return;
+ }
+
+ mSurfaceListener->onBuffersDiscarded(discardedBufs);
+}
+
}; // namespace android
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 690a85f..17617bc 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -189,8 +189,12 @@
sp<IProducerListener> mLinkedToDeath;
// mConnectedProducerListener is used to handle the onBufferReleased
- // notification.
+ // and onBuffersDiscarded notification.
sp<IProducerListener> mConnectedProducerListener;
+ // mBufferReleasedCbEnabled is used to indicate whether onBufferReleased()
+ // callback is registered by the listener. When set to false,
+ // mConnectedProducerListener will not trigger onBufferReleased() callback.
+ bool mBufferReleasedCbEnabled;
// mSlots is an array of buffer slots that must be mirrored on the producer
// side. This allows buffer ownership to be transferred between the producer
diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h
index a13d8e4..32a3690 100644
--- a/libs/gui/include/gui/IProducerListener.h
+++ b/libs/gui/include/gui/IProducerListener.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_GUI_IPRODUCERLISTENER_H
#define ANDROID_GUI_IPRODUCERLISTENER_H
+#include <vector>
+
#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>
#include <binder/IInterface.h>
@@ -44,6 +46,9 @@
// multiple threads.
virtual void onBufferReleased() = 0; // Asynchronous
virtual bool needsReleaseNotify() = 0;
+ // onBuffersFreed is called from IGraphicBufferConsumer::discardFreeBuffers
+ // to notify the producer that certain free buffers are discarded by the consumer.
+ virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) = 0; // Asynchronous
};
class IProducerListener : public ProducerListener, public IInterface
@@ -65,6 +70,7 @@
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
virtual bool needsReleaseNotify();
+ virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);
};
class DummyProducerListener : public BnProducerListener
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 5c6a1ee..a5641b0 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -20,6 +20,7 @@
#include <gui/BufferQueueDefs.h>
#include <gui/HdrMetadata.h>
#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
#include <ui/ANativeObjectBase.h>
#include <ui/GraphicTypes.h>
@@ -35,6 +36,21 @@
class ISurfaceComposer;
+/* This is the same as ProducerListener except that onBuffersDiscarded is
+ * called with a vector of graphic buffers instead of buffer slots.
+ */
+class SurfaceListener : public virtual RefBase
+{
+public:
+ SurfaceListener() = default;
+ virtual ~SurfaceListener() = default;
+
+ virtual void onBufferReleased() = 0;
+ virtual bool needsReleaseNotify() = 0;
+
+ virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) = 0;
+};
+
/*
* An implementation of ANativeWindow that feeds graphics buffers into a
* BufferQueue.
@@ -283,6 +299,10 @@
sp<Fence>* outFence);
virtual int attachBuffer(ANativeWindowBuffer*);
+ virtual int connect(
+ int api, bool reportBufferRemoval,
+ const sp<SurfaceListener>& sListener);
+
// When client connects to Surface with reportBufferRemoval set to true, any buffers removed
// from this Surface will be collected and returned here. Once this method returns, these
// buffers will no longer be referenced by this Surface unless they are attached to this
@@ -299,6 +319,26 @@
enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
+ class ProducerListenerProxy : public BnProducerListener {
+ public:
+ ProducerListenerProxy(wp<Surface> parent, sp<SurfaceListener> listener)
+ : mParent(parent), mSurfaceListener(listener) {}
+ virtual ~ProducerListenerProxy() {}
+
+ virtual void onBufferReleased() {
+ mSurfaceListener->onBufferReleased();
+ }
+
+ virtual bool needsReleaseNotify() {
+ return mSurfaceListener->needsReleaseNotify();
+ }
+
+ virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);
+ private:
+ wp<Surface> mParent;
+ sp<SurfaceListener> mSurfaceListener;
+ };
+
void querySupportedTimestampsLocked() const;
void freeAllBuffers();
@@ -466,6 +506,10 @@
bool mReportRemovedBuffers = false;
std::vector<sp<GraphicBuffer>> mRemovedBuffers;
+
+ sp<IProducerListener> mListenerProxy;
+ status_t getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots,
+ std::vector<sp<GraphicBuffer>>* outBuffers);
};
} // namespace android
diff --git a/libs/gui/sysprop/Android.bp b/libs/gui/sysprop/Android.bp
index e7f7c1f..e090c49 100644
--- a/libs/gui/sysprop/Android.bp
+++ b/libs/gui/sysprop/Android.bp
@@ -1,5 +1,9 @@
sysprop_library {
name: "LibGuiProperties",
+ apex_available: [
+ "com.android.media",
+ "com.android.media.swcodec",
+ ],
srcs: ["*.sysprop"],
api_packages: ["android.sysprop"],
property_owner: "Platform",
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 119e888..406f21f 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -998,12 +998,31 @@
ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
}
+struct BufferDiscardedListener : public BnProducerListener {
+public:
+ BufferDiscardedListener() = default;
+ virtual ~BufferDiscardedListener() = default;
+
+ virtual void onBufferReleased() {}
+ virtual bool needsReleaseNotify() { return false; }
+ virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) {
+ mDiscardedSlots.insert(mDiscardedSlots.end(), slots.begin(), slots.end());
+ }
+
+ const std::vector<int32_t>& getDiscardedSlots() const { return mDiscardedSlots; }
+private:
+ // No need to use lock given the test triggers the listener in the same
+ // thread context.
+ std::vector<int32_t> mDiscardedSlots;
+};
+
TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
createBufferQueue();
sp<DummyConsumer> dc(new DummyConsumer);
ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
IGraphicBufferProducer::QueueBufferOutput output;
- ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
+ sp<BufferDiscardedListener> pl(new BufferDiscardedListener);
+ ASSERT_EQ(OK, mProducer->connect(pl,
NATIVE_WINDOW_API_CPU, false, &output));
int slot = BufferQueue::INVALID_BUFFER_SLOT;
@@ -1044,12 +1063,19 @@
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
+ int releasedSlot = item.mSlot;
+
// Acquire 1 buffer, leaving 1 filled buffer in queue
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
// Now discard the free buffers
ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
+ // Check onBuffersDiscarded is called with correct slots
+ auto buffersDiscarded = pl->getDiscardedSlots();
+ ASSERT_EQ(buffersDiscarded.size(), 1);
+ ASSERT_EQ(buffersDiscarded[0], releasedSlot);
+
// Check no free buffers in dump
String8 dumpString;
mConsumer->dumpState(String8{}, &dumpString);
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 386f731..03b9cd7 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -133,27 +133,6 @@
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
}
- void expectMotionEvent(int motionEventType, int x, int y) {
- InputEvent *ev = consumeEvent();
- ASSERT_NE(ev, nullptr);
- ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION);
- MotionEvent *mev = static_cast<MotionEvent *>(ev);
- EXPECT_EQ(motionEventType, mev->getAction());
- EXPECT_EQ(x, mev->getX(0));
- EXPECT_EQ(y, mev->getY(0));
- }
-
- void expectNoMotionEvent(int motionEventType) {
- InputEvent *ev = consumeEvent();
- if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) {
- // Didn't find an event or a motion event so assume action didn't occur.
- return;
- }
-
- MotionEvent *mev = static_cast<MotionEvent *>(ev);
- EXPECT_NE(motionEventType, mev->getAction());
- }
-
~InputSurface() {
mInputFlinger->unregisterInputChannel(mServerChannel);
}
@@ -278,15 +257,6 @@
}
}
-void injectMotionEvent(std::string event, int x, int y) {
- char *buf1, *buf2;
- asprintf(&buf1, "%d", x);
- asprintf(&buf2, "%d", y);
- if (fork() == 0) {
- execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL);
- }
-}
-
TEST_F(InputSurfacesTest, can_receive_input) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->showAt(100, 100);
@@ -435,9 +405,11 @@
surface->expectTap(1, 1);
}
-// Ensure we send the input to the right surface when the surface visibility changes due to the
-// first buffer being submitted. ref: b/120839715
-TEST_F(InputSurfacesTest, input_respects_buffer_layer_buffer) {
+// TODO(b/139494112) update tests once we define expected behavior
+// Ensure we still send input to the surface regardless of surface visibility changes due to the
+// first buffer being submitted or alpha changes.
+// Original bug ref: b/120839715
+TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
@@ -446,14 +418,14 @@
bufferSurface->showAt(10, 10);
injectTap(11, 11);
- bgSurface->expectTap(1, 1);
+ bufferSurface->expectTap(1, 1);
postBuffer(bufferSurface->mSurfaceControl);
injectTap(11, 11);
bufferSurface->expectTap(1, 1);
}
-TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
+TEST_F(InputSurfacesTest, input_ignores_buffer_layer_alpha) {
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
@@ -468,10 +440,10 @@
bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
injectTap(11, 11);
- bgSurface->expectTap(1, 1);
+ bufferSurface->expectTap(1, 1);
}
-TEST_F(InputSurfacesTest, input_respects_color_layer_alpha) {
+TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
@@ -484,7 +456,7 @@
fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
injectTap(11, 11);
- bgSurface->expectTap(1, 1);
+ fgSurface->expectTap(1, 1);
}
TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
@@ -504,26 +476,6 @@
bgSurface->expectTap(1, 1);
}
-TEST_F(InputSurfacesTest, transfer_touch_focus) {
- std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100);
-
- fromSurface->showAt(10, 10);
- injectMotionEvent("DOWN", 11, 11);
- fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1);
-
- std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100);
- toSurface->showAt(10, 10);
-
- sp<IBinder> fromToken = fromSurface->mServerChannel->getToken();
- sp<IBinder> toToken = toSurface->mServerChannel->getToken();
- SurfaceComposerClient::Transaction t;
- t.transferTouchFocus(fromToken, toToken).apply(true);
-
- injectMotionEvent("UP", 11, 11);
- toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1);
- fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP);
-}
-
TEST_F(InputSurfacesTest, input_respects_outscreen) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->showAt(-1, -1);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d370858..a851687 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -57,6 +57,37 @@
static constexpr uint64_t NO_FRAME_INDEX = std::numeric_limits<uint64_t>::max();
+class DummySurfaceListener : public SurfaceListener {
+public:
+ DummySurfaceListener(bool enableReleasedCb = false) :
+ mEnableReleaseCb(enableReleasedCb),
+ mBuffersReleased(0) {}
+ virtual ~DummySurfaceListener() = default;
+
+ virtual void onBufferReleased() {
+ mBuffersReleased++;
+ }
+ virtual bool needsReleaseNotify() {
+ return mEnableReleaseCb;
+ }
+ virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) {
+ mDiscardedBuffers.insert(mDiscardedBuffers.end(), buffers.begin(), buffers.end());
+ }
+
+ int getReleaseNotifyCount() const {
+ return mBuffersReleased;
+ }
+ const std::vector<sp<GraphicBuffer>>& getDiscardedBuffers() const {
+ return mDiscardedBuffers;
+ }
+private:
+ // No need to use lock given the test triggers the listener in the same
+ // thread context.
+ bool mEnableReleaseCb;
+ int32_t mBuffersReleased;
+ std::vector<sp<GraphicBuffer>> mDiscardedBuffers;
+};
+
class SurfaceTest : public ::testing::Test {
protected:
SurfaceTest() {
@@ -88,6 +119,86 @@
mComposerClient->dispose();
}
+ void testSurfaceListener(bool hasSurfaceListener, bool enableReleasedCb,
+ int32_t extraDiscardedBuffers) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<DummyConsumer> dummyConsumer(new DummyConsumer);
+ consumer->consumerConnect(dummyConsumer, false);
+ consumer->setConsumerName(String8("TestConsumer"));
+
+ sp<Surface> surface = new Surface(producer);
+ sp<ANativeWindow> window(surface);
+ sp<DummySurfaceListener> listener;
+ if (hasSurfaceListener) {
+ listener = new DummySurfaceListener(enableReleasedCb);
+ }
+ ASSERT_EQ(OK, surface->connect(
+ NATIVE_WINDOW_API_CPU,
+ /*reportBufferRemoval*/true,
+ /*listener*/listener));
+ const int BUFFER_COUNT = 4 + extraDiscardedBuffers;
+ ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(window.get(), BUFFER_COUNT));
+
+ ANativeWindowBuffer* buffers[BUFFER_COUNT];
+ // Dequeue first to allocate a number of buffers
+ for (int i = 0; i < BUFFER_COUNT; i++) {
+ ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffers[i]));
+ }
+ for (int i = 0; i < BUFFER_COUNT; i++) {
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffers[i], -1));
+ }
+
+ ANativeWindowBuffer* buffer;
+ // Fill BUFFER_COUNT-1 buffers
+ for (int i = 0; i < BUFFER_COUNT-1; i++) {
+ ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffer));
+ ASSERT_EQ(NO_ERROR, window->queueBuffer(window.get(), buffer, -1));
+ }
+
+ // Dequeue 1 buffer
+ ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffer));
+
+ // Acquire and free 1+extraDiscardedBuffers buffer, check onBufferReleased is called.
+ std::vector<BufferItem> releasedItems;
+ releasedItems.resize(1+extraDiscardedBuffers);
+ for (int i = 0; i < releasedItems.size(); i++) {
+ ASSERT_EQ(NO_ERROR, consumer->acquireBuffer(&releasedItems[i], 0));
+ ASSERT_EQ(NO_ERROR, consumer->releaseBuffer(releasedItems[i].mSlot,
+ releasedItems[i].mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
+ Fence::NO_FENCE));
+ }
+ int32_t expectedReleaseCb = (enableReleasedCb ? releasedItems.size() : 0);
+ if (hasSurfaceListener) {
+ ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount());
+ }
+
+ // Acquire 1 buffer, leaving 1+extraDiscardedBuffers filled buffer in queue
+ BufferItem item;
+ ASSERT_EQ(NO_ERROR, consumer->acquireBuffer(&item, 0));
+
+ // Discard free buffers
+ ASSERT_EQ(NO_ERROR, consumer->discardFreeBuffers());
+
+ if (hasSurfaceListener) {
+ ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount());
+
+ // Check onBufferDiscarded is called with correct buffer
+ auto discardedBuffers = listener->getDiscardedBuffers();
+ ASSERT_EQ(discardedBuffers.size(), releasedItems.size());
+ for (int i = 0; i < releasedItems.size(); i++) {
+ ASSERT_EQ(discardedBuffers[i], releasedItems[i].mGraphicBuffer);
+ }
+
+ ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount());
+ }
+
+ // Disconnect the surface
+ ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU));
+ }
+
sp<Surface> mSurface;
sp<SurfaceComposerClient> mComposerClient;
sp<SurfaceControl> mSurfaceControl;
@@ -480,6 +591,21 @@
ASSERT_LE(removedBuffers.size(), 1u);
}
+TEST_F(SurfaceTest, SurfaceListenerTest) {
+ // Test discarding 1 free buffers with no listener
+ testSurfaceListener(/*hasListener*/false, /*enableReleaseCb*/false, /*extraDiscardedBuffers*/0);
+ // Test discarding 2 free buffers with no listener
+ testSurfaceListener(/*hasListener*/false, /*enableReleaseCb*/false, /*extraDiscardedBuffers*/1);
+ // Test discarding 1 free buffers with a listener, disabling onBufferReleased
+ testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/false, /*extraDiscardedBuffers*/0);
+ // Test discarding 2 free buffers with a listener, disabling onBufferReleased
+ testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/false, /*extraDiscardedBuffers*/1);
+ // Test discarding 1 free buffers with a listener, enabling onBufferReleased
+ testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/true, /*extraDiscardedBuffers*/0);
+ // Test discarding 3 free buffers with a listener, enabling onBufferReleased
+ testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/true, /*extraDiscardedBuffers*/2);
+}
+
TEST_F(SurfaceTest, TestGetLastDequeueStartTime) {
sp<ANativeWindow> anw(mSurface);
ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU));
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index d6a73bf..de3a23d 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -45,16 +45,6 @@
IBinder::FLAG_ONEWAY);
}
- virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
- Parcel data, reply;
- data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
-
- data.writeStrongBinder(fromToken);
- data.writeStrongBinder(toToken);
- remote()->transact(BnInputFlinger::TRANSFER_TOUCH_FOCUS, data, &reply,
- IBinder::FLAG_ONEWAY);
- }
-
virtual void registerInputChannel(const sp<InputChannel>& channel) {
Parcel data, reply;
data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
@@ -104,13 +94,6 @@
unregisterInputChannel(channel);
break;
}
- case TRANSFER_TOUCH_FOCUS: {
- CHECK_INTERFACE(IInputFlinger, data, reply);
- sp<IBinder> fromToken = data.readStrongBinder();
- sp<IBinder> toToken = data.readStrongBinder();
- transferTouchFocus(fromToken, toToken);
- break;
- }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 5f1c71e..b54ce0f 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -132,6 +132,17 @@
status_t error =
mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle);
+ size_t bufSize;
+
+ // if stride has no meaning or is too large,
+ // approximate size with the input width instead
+ if ((*stride) != 0 &&
+ std::numeric_limits<size_t>::max() / height / (*stride) < static_cast<size_t>(bpp)) {
+ bufSize = static_cast<size_t>(width) * height * bpp;
+ } else {
+ bufSize = static_cast<size_t>((*stride)) * height * bpp;
+ }
+
if (error == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
@@ -142,7 +153,7 @@
rec.format = format;
rec.layerCount = layerCount;
rec.usage = usage;
- rec.size = static_cast<size_t>(height * (*stride) * bpp);
+ rec.size = bufSize;
rec.requestorName = std::move(requestorName);
list.add(*handle, rec);
diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS
index 97ead21..203a739 100644
--- a/libs/ui/OWNERS
+++ b/libs/ui/OWNERS
@@ -1,7 +1,6 @@
+chrisforbes@google.com
lpy@google.com
-marissaw@google.com
mathias@google.com
romainguy@google.com
stoza@google.com
-jwcai@google.com
-tianyuj@google.com
+vhau@google.com
diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h
index faec978..0635727 100644
--- a/libs/ui/include/ui/GraphicBufferAllocator.h
+++ b/libs/ui/include/ui/GraphicBufferAllocator.h
@@ -54,7 +54,7 @@
void dump(std::string& res) const;
static void dumpToSystemLog();
-private:
+protected:
struct alloc_rec_t {
uint32_t width;
uint32_t height;
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 99434b7..0a07a48 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,6 +29,26 @@
}
cc_test {
+ name: "GraphicBufferAllocator_test",
+ header_libs: [
+ "libdvr_headers",
+ "libnativewindow_headers",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ shared_libs: [
+ "liblog",
+ "libui",
+ ],
+ srcs: [
+ "GraphicBufferAllocator_test.cpp",
+ "mock/MockGrallocAllocator.cpp",
+ ],
+ cflags: ["-Wall", "-Werror"],
+}
+
+cc_test {
name: "GraphicBuffer_test",
header_libs: [
"libdvr_headers",
diff --git a/libs/ui/tests/GraphicBufferAllocator_test.cpp b/libs/ui/tests/GraphicBufferAllocator_test.cpp
new file mode 100644
index 0000000..efca083
--- /dev/null
+++ b/libs/ui/tests/GraphicBufferAllocator_test.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 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 "GraphicBufferAllocatorTest"
+
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+
+#include <gtest/gtest.h>
+
+#include "mock/MockGrallocAllocator.h"
+
+#include <algorithm>
+#include <limits>
+
+namespace android {
+
+namespace {
+
+constexpr uint32_t kTestWidth = 1024;
+constexpr uint32_t kTestHeight = 1;
+constexpr uint32_t kTestLayerCount = 1;
+constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+
+} // namespace
+
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+
+class TestableGraphicBufferAllocator : public GraphicBufferAllocator {
+public:
+ TestableGraphicBufferAllocator() {
+ mAllocator = std::make_unique<const mock::MockGrallocAllocator>();
+ }
+ void setUpAllocateExpectations(status_t err, uint32_t stride) {
+ std::cout << "Setting expected stride to " << stride << std::endl;
+ EXPECT_CALL(*(reinterpret_cast<const mock::MockGrallocAllocator*>(mAllocator.get())),
+ allocate)
+ .WillOnce(DoAll(SetArgPointee<6>(stride), Return(err)));
+ }
+ std::unique_ptr<const GrallocAllocator>& getAllocator() { return mAllocator; }
+};
+
+class GraphicBufferAllocatorTest : public testing::Test {
+public:
+ GraphicBufferAllocatorTest() : mAllocator() {}
+ const TestableGraphicBufferAllocator& getAllocator() { return mAllocator; }
+
+protected:
+ TestableGraphicBufferAllocator mAllocator;
+};
+
+TEST_F(GraphicBufferAllocatorTest, AllocateNoError) {
+ mAllocator.setUpAllocateExpectations(NO_ERROR, kTestWidth);
+ android::PixelFormat format = PIXEL_FORMAT_RGBA_8888;
+ uint32_t stride = 0;
+ buffer_handle_t handle;
+ status_t err = mAllocator.allocate(kTestWidth, kTestHeight, format, kTestLayerCount, kTestUsage,
+ &handle, &stride, 0, "GraphicBufferAllocatorTest");
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(kTestWidth, stride);
+}
+
+TEST_F(GraphicBufferAllocatorTest, AllocateZeroStride) {
+ android::PixelFormat format = PIXEL_FORMAT_RGBA_8888;
+ uint32_t expectedStride = 0;
+
+ mAllocator.setUpAllocateExpectations(NO_ERROR, expectedStride);
+ uint32_t stride = 0;
+ buffer_handle_t handle;
+ // a divide by zero would cause a crash
+ status_t err = mAllocator.allocate(kTestWidth, kTestHeight, format, kTestLayerCount, kTestUsage,
+ &handle, &stride, 0, "GraphicBufferAllocatorTest");
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(expectedStride, stride);
+}
+
+TEST_F(GraphicBufferAllocatorTest, AllocateLargeStride) {
+ uint32_t height = std::numeric_limits<uint32_t>::max();
+ uint32_t bpp = 4;
+ android::PixelFormat format = PIXEL_FORMAT_RGBA_8888;
+
+ if (std::numeric_limits<size_t>::max() / height / bpp >= std::numeric_limits<uint32_t>::max()) {
+ std::cout << "stride cannot cause overflow" << std::endl;
+ GTEST_SUCCEED() << "stride cannot cause overflow";
+ return;
+ }
+ uint32_t width = std::numeric_limits<size_t>::max() / height / bpp;
+
+ uint32_t expectedStride = std::numeric_limits<uint32_t>::max();
+
+ mAllocator.setUpAllocateExpectations(NO_ERROR, expectedStride);
+ uint32_t stride = 0;
+ buffer_handle_t handle;
+ // an overflow would cause a crash
+ status_t err = mAllocator.allocate(width, height, format, kTestLayerCount, kTestUsage, &handle,
+ &stride, 0, "GraphicBufferAllocatorTest");
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(expectedStride, stride);
+}
+} // namespace android
diff --git a/libs/ui/tests/mock/MockGrallocAllocator.cpp b/libs/ui/tests/mock/MockGrallocAllocator.cpp
new file mode 100644
index 0000000..d71e25f
--- /dev/null
+++ b/libs/ui/tests/mock/MockGrallocAllocator.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MockGrallocAllocator.h"
+
+namespace android {
+
+namespace mock {
+
+MockGrallocAllocator::MockGrallocAllocator() = default;
+MockGrallocAllocator::~MockGrallocAllocator() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/libs/ui/tests/mock/MockGrallocAllocator.h b/libs/ui/tests/mock/MockGrallocAllocator.h
new file mode 100644
index 0000000..22c80a4
--- /dev/null
+++ b/libs/ui/tests/mock/MockGrallocAllocator.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include <ui/Gralloc.h>
+
+namespace android {
+
+class GraphicBuffer;
+
+namespace mock {
+
+class MockGrallocAllocator : public GrallocAllocator {
+public:
+ MockGrallocAllocator();
+ ~MockGrallocAllocator() override;
+
+ MOCK_METHOD(bool, isLoaded, (), (const, override));
+ MOCK_METHOD(std::string, dumpDebugInfo, (), (const, override));
+ MOCK_METHOD(status_t, allocate,
+ (uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles),
+ (const, override));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index ecbfdba..9bc70ea 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -535,13 +535,13 @@
*message = Message{info};
auto* state = static_cast<MessageState*>(message->GetState());
state->request = std::move(request);
- if (request.send_len > 0 && !request.is_impulse) {
- state->request_data.resize(request.send_len);
+ if (state->request.send_len > 0 && !state->request.is_impulse) {
+ state->request_data.resize(state->request.send_len);
status = ReceiveData(channel_fd, state->request_data.data(),
state->request_data.size());
}
- if (status && request.is_impulse)
+ if (status && state->request.is_impulse)
status = ReenableEpollEvent(channel_fd);
if (!status) {
diff --git a/opengl/libagl/Android.bp b/opengl/libagl/Android.bp
index f5bf015..c4fca1b 100644
--- a/opengl/libagl/Android.bp
+++ b/opengl/libagl/Android.bp
@@ -33,14 +33,6 @@
arm: {
cflags: ["-fstrict-aliasing"],
},
-
- mips: {
- cflags: [
- "-fstrict-aliasing",
- // The graphics code can generate division by zero
- "-mno-check-zero-division",
- ],
- },
},
}
@@ -67,12 +59,6 @@
"iterators.S",
],
},
-
- mips: {
- rev6: {
- srcs: ["arch-mips/fixed_asm.S"],
- },
- },
},
relative_install_path: "egl",
diff --git a/opengl/libagl/arch-mips/fixed_asm.S b/opengl/libagl/arch-mips/fixed_asm.S
deleted file mode 100644
index a30ffc5..0000000
--- a/opengl/libagl/arch-mips/fixed_asm.S
+++ /dev/null
@@ -1,61 +0,0 @@
-/* libs/opengles/arch-mips/fixed_asm.S
-**
-** Copyright 2012, 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.
-*/
-
-
- .text
- .align 4
-
-/*
- * this version rounds-to-nearest and saturates numbers
- * outside the range (but not NaNs).
- */
-
- .global gglFloatToFixed
- .ent gglFloatToFixed
- .type gglFloatToFixed, @function
-gglFloatToFixed:
-#if !defined(__mips_soft_float)
- mfc1 $a0,$f12
-#endif
- srl $t0,$a0,31 /* t0 <- sign bit */
- srl $t1,$a0,23
- andi $t1,$t1,0xff /* get the e */
- li $t2,0x8e
- subu $t1,$t2,$t1 /* t1=127+15-e */
- blez $t1,0f /* t1<=0? */
- sll $t2,$a0,8 /* mantissa<<8 */
- lui $t3,0x8000
- or $t2,$t2,$t3 /* add the missing 1 */
- subu $t1,$t1,1
- srl $v0,$t2,$t1
- sltiu $t3,$t1,32 /* t3=1 if t1<32, else t3=0. t1>=32 means the float value is too small. */
- andi $t4,$v0,0x1
- srl $v0,$v0,1 /* scale to 16.16 */
- addu $v0,$v0,$t4 /* round-to-nearest */
- subu $t2,$zero,$v0
- movn $v0,$t2,$t0 /* if negative? */
- or $t1,$a0,$zero /* a0=0? */
- movz $v0,$zero,$t1
- movz $v0,$zero,$t3 /* t3=0 then res=0 */
- jr $ra
-0:
- lui $t1,0x8000
- and $v0,$a0,$t1 /* keep only the sign bit */
- li $t1,0x7fffffff
- movz $v0,$t1,$t0 /* positive, maximum value */
- jr $ra
- .end gglFloatToFixed
diff --git a/opengl/libagl/fp.cpp b/opengl/libagl/fp.cpp
index a7a4f7b..ae5f1fe 100644
--- a/opengl/libagl/fp.cpp
+++ b/opengl/libagl/fp.cpp
@@ -19,7 +19,7 @@
// ----------------------------------------------------------------------------
-#if !(defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6))
+#if !defined(__arm__)
GGLfixed gglFloatToFixed(float v) {
return GGLfixed(floorf(v * 65536.0f + 0.5f));
}
diff --git a/opengl/libagl/matrix.h b/opengl/libagl/matrix.h
index cafc119..c9a38a9 100644
--- a/opengl/libagl/matrix.h
+++ b/opengl/libagl/matrix.h
@@ -74,30 +74,6 @@
);
return r;
-#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
-
- GLfixed res;
- int32_t t1,t2,t3;
- asm(
- "mult %[a], %[a] \r\n"
- "li %[res],0x8000 \r\n"
- "madd %[b],%[b] \r\n"
- "move %[t3],$zero \r\n"
- "madd %[c],%[c] \r\n"
- "mflo %[t1]\r\n"
- "mfhi %[t2]\r\n"
- "addu %[t1],%[res],%[t1]\r\n" /*add 0x8000*/
- "sltu %[t3],%[t1],%[res]\r\n"
- "addu %[t2],%[t2],%[t3]\r\n"
- "srl %[res],%[t1],16\r\n"
- "sll %[t2],%[t2],16\r\n"
- "or %[res],%[res],%[t2]\r\n"
- : [res]"=&r"(res),[t1]"=&r"(t1),[t2]"=&r"(t2),[t3]"=&r"(t3)
- : [a] "r" (a),[b] "r" (b),[c] "r" (c)
- : "%hi","%lo"
- );
- return res;
-
#else
return (( int64_t(a)*a +
@@ -160,26 +136,6 @@
);
return r;
-#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
-
- GLfixed res;
- int32_t t1,t2;
- asm(
- "mult %[a0],%[b0] \r\n"
- "madd %[a1],%[b1] \r\n"
- "madd %[a2],%[b2] \r\n"
- "mflo %[t2]\r\n"
- "mfhi %[t1]\r\n"
- "srl %[t2],%[t2],16\r\n"
- "sll %[t1],%[t1],16\r\n"
- "or %[t2],%[t2],%[t1]\r\n"
- "addu %[res],%[t2],%[c]"
- : [res]"=&r"(res),[t1]"=&r"(t1),[t2]"=&r"(t2)
- : [a0] "r" (a0),[b0] "r" (b0),[a1] "r" (a1),[b1] "r" (b1),[a2] "r" (a2),[b2] "r" (b2),[c] "r" (c)
- : "%hi","%lo"
- );
- return res;
-
#else
return (( int64_t(a0)*b0 +
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 67d69b4..a58e87c 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -158,13 +158,16 @@
// NOTE: This is only valid if the backend is OpenGL
attrs.push_back(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE);
attrs.push_back(vendorEGL);
+
+ // Context virtualization is only available on GL back-end.
+ // Needed to support threading with GL back-end
+ attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
+ attrs.push_back(EGL_FALSE);
break;
default:
- ALOGV("%s: Requesting Unknown (%d) ANGLE back-end", __FUNCTION__, cnx->angleBackend);
+ ALOGE("%s: Requesting Unknown (%d) ANGLE back-end", __FUNCTION__, cnx->angleBackend);
break;
}
- attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
- attrs.push_back(EGL_FALSE);
return true;
}
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index 41fcf1b..9efd38f 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -1,6 +1,18 @@
#!/bin/bash
set -u
set -e
+
+if [ -z "$ANDROID_BUILD_TOP" ] ; then
+ echo "ANDROID_BUILD_TOP is not set, did you run lunch?"
+ exit 1
+fi
+
+# Avoid spewing files in any location other than the intended one.
+if [ ! -x "$PWD/gen" ] ; then
+ echo "Run this script from its parent directory".
+ exit 1
+fi
+
rm -rf out generated
mkdir out
@@ -92,7 +104,7 @@
# Add UnsupportedAppUsage.java to known sources.
mkdir -p out/android/compat/annotation
-cp ../../../../../tools/platform-compat/annotation/src/java/android/compat/annotation/UnsupportedAppUsage.java out/android/compat/annotation
+cp ${ANDROID_BUILD_TOP}/tools/platform-compat/java/android/compat/annotation/UnsupportedAppUsage.java out/android/compat/annotation
pushd out > /dev/null
mkdir classes
@@ -153,23 +165,23 @@
fi
}
-compareGenerated ../../../../base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp
-compareGenerated ../../../../base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java
+compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp
+compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java
for x in GL.java GL10.java GL10Ext.java GL11.java GL11Ext.java GL11ExtensionPack.java
do
- compareGenerated ../../../../base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x
+ compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x
done
for x in EGL14 EGL15 EGLExt GLES10 GLES10Ext GLES11 GLES11Ext GLES20 GLES30 GLES31 GLES31Ext GLES32
do
- compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java
- compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp
+ compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/android/opengl generated/android/opengl ${x}.java
+ compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/core/jni generated/C android_opengl_${x}.cpp
done
for x in EGLConfig EGLContext EGLDisplay EGLObjectHandle EGLSurface EGLImage EGLSync
do
- compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java
+ compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/android/opengl generated/android/opengl ${x}.java
done
if [ $KEEP_GENERATED == "0" ] ; then
diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
index 9932556..951ecff 100644
--- a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
+++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
@@ -21,8 +21,8 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.SurfaceTexture;
import android.view.Surface;
-import android.view.SurfaceView;
import android.view.SurfaceHolder;
+import android.view.SurfaceView;
/**
* EGL 1.4
diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
index afcc3eb..32c9d7d 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
+++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
@@ -19,6 +19,7 @@
package com.google.android.gles_jni;
import android.app.AppGlobals;
+import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.os.Build;
@@ -26,6 +27,7 @@
import android.util.Log;
import java.nio.Buffer;
+
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL10Ext;
import javax.microedition.khronos.opengles.GL11;
@@ -55,6 +57,7 @@
private boolean have_OES_framebuffer_object;
private boolean have_OES_texture_cube_map;
+ @UnsupportedAppUsage
public GLImpl() {
}
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index 6a7f279..ef1a224 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -82,7 +82,7 @@
// Check if the "deep touch" feature is on.
static bool deepPressEnabled() {
std::string flag_value = server_configurable_flags::GetServerConfigurableFlag(
- INPUT_NATIVE_BOOT, DEEP_PRESS_ENABLED, "false");
+ INPUT_NATIVE_BOOT, DEEP_PRESS_ENABLED, "true");
std::transform(flag_value.begin(), flag_value.end(), flag_value.begin(), ::tolower);
if (flag_value == "1" || flag_value == "true") {
ALOGI("Deep press feature enabled.");
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 359325f..7d30672 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -119,10 +119,6 @@
}
}
-void InputManager::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
- mDispatcher->transferTouchFocus(fromToken, toToken);
-}
-
// Used by tests only.
void InputManager::registerInputChannel(const sp<InputChannel>& channel) {
IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index f3da324..40f66d8 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -96,7 +96,6 @@
virtual void setInputWindows(const std::vector<InputWindowInfo>& handles,
const sp<ISetInputWindowsListener>& setInputWindowsListener);
- virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
virtual void registerInputChannel(const sp<InputChannel>& channel);
virtual void unregisterInputChannel(const sp<InputChannel>& channel);
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 8d05640..a4d9e4e 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -18,10 +18,12 @@
#include "Connection.h"
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <cutils/atomic.h>
#include <inttypes.h>
+using android::base::GetBoolProperty;
using android::base::StringPrintf;
namespace android::inputdispatcher {
@@ -133,7 +135,11 @@
KeyEntry::~KeyEntry() {}
void KeyEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
+ msg += StringPrintf("KeyEvent");
+ if (!GetBoolProperty("ro.debuggable", false)) {
+ return;
+ }
+ msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
"flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
"repeatCount=%d), policyFlags=0x%08x",
deviceId, source, displayId, keyActionToString(action).c_str(), flags,
@@ -186,7 +192,11 @@
MotionEntry::~MotionEntry() {}
void MotionEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
+ msg += StringPrintf("MotionEvent");
+ if (!GetBoolProperty("ro.debuggable", false)) {
+ return;
+ }
+ msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
"buttonState=0x%08x, "
"classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index d8b352c..973b4f9 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -42,7 +42,6 @@
virtual status_t dump(int fd, const Vector<String16>& args);
void setInputWindows(const std::vector<InputWindowInfo>&,
const sp<ISetInputWindowsListener>&) {}
- void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}
void registerInputChannel(const sp<InputChannel>&) {}
void unregisterInputChannel(const sp<InputChannel>&) {}
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index 7927fa9..e33bedb 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -35,11 +35,7 @@
return false;
}
-bool ContainerLayer::canReceiveInput() const {
- return !isHiddenByPolicy();
-}
void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&, const ui::Transform&,
const Rect&, int32_t, const ui::Dataspace) {}
-
} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 7222a3e..e6dbfcc 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,8 +31,6 @@
const char* getTypeId() const override { return "ContainerLayer"; }
bool isVisible() const override;
- bool canReceiveInput() const override;
-
void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
const Rect& viewport, int32_t supportedPerFrameMetadata,
const ui::Dataspace targetDataspace) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index dda15e9..3e6dded 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2106,7 +2106,7 @@
}
bool Layer::canReceiveInput() const {
- return isVisible();
+ return !isHiddenByPolicy();
}
compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index f2bc65d..6bb999c 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -3,7 +3,6 @@
alecmouri@google.com
chaviw@google.com
lpy@google.com
-marissaw@google.com
racarr@google.com
steventhomas@google.com
stoza@google.com
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 60b3a11..1788560 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -574,9 +574,9 @@
mRefreshRateConfigs.getRefreshRate(RefreshRateType::PERFORMANCE);
if (performanceRefreshRate && isDisplayConfigAllowed(performanceRefreshRate->configId)) {
- setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::None);
+ setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::Changed);
} else {
- setRefreshRateTo(RefreshRateType::DEFAULT, Scheduler::ConfigEvent::None);
+ setRefreshRateTo(RefreshRateType::DEFAULT, Scheduler::ConfigEvent::Changed);
}
}));
}
@@ -3029,7 +3029,7 @@
setInputWindowsFinished();
}
- executeInputWindowCommands();
+ mInputWindowCommands.clear();
}
void SurfaceFlinger::updateInputWindowInfo() {
@@ -3053,19 +3053,6 @@
mPendingInputWindowCommands.clear();
}
-void SurfaceFlinger::executeInputWindowCommands() {
- for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
- if (transferTouchFocusCommand.fromToken != nullptr &&
- transferTouchFocusCommand.toToken != nullptr &&
- transferTouchFocusCommand.fromToken != transferTouchFocusCommand.toToken) {
- mInputFlinger->transferTouchFocus(transferTouchFocusCommand.fromToken,
- transferTouchFocusCommand.toToken);
- }
- }
-
- mInputWindowCommands.clear();
-}
-
void SurfaceFlinger::updateCursorAsync()
{
for (const auto& [token, display] : mDisplays) {
@@ -6236,7 +6223,7 @@
return NO_ERROR;
}
- postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS {
+ postMessageSync(new LambdaMessage([&]() {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set allowed display configs for invalid display token %p",
@@ -6244,6 +6231,7 @@
} else if (display->isVirtual()) {
ALOGW("Attempt to set allowed display configs for virtual display");
} else {
+ Mutex::Autolock lock(mStateLock);
setAllowedDisplayConfigsInternal(display, allowedConfigs);
}
}));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 49bb574..8e4203a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -554,7 +554,6 @@
void updateInputFlinger();
void updateInputWindowInfo();
void commitInputWindowCommands() REQUIRES(mStateLock);
- void executeInputWindowCommands();
void setInputWindowsFinished();
void updateCursorAsync();
diff --git a/services/surfaceflinger/tests/AndroidTest.xml b/services/surfaceflinger/tests/AndroidTest.xml
index 8315037..000628f 100644
--- a/services/surfaceflinger/tests/AndroidTest.xml
+++ b/services/surfaceflinger/tests/AndroidTest.xml
@@ -18,6 +18,7 @@
<option name="cleanup" value="true" />
<option name="push" value="SurfaceFlinger_test->/data/local/tmp/SurfaceFlinger_test" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
<option name="test-suite-tag" value="apct" />
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />