Merge "Add a filegroup for AIDL files in frameworks/native/aidl"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 52cd831..e296eaa 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1256,7 +1256,6 @@
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
RunCommand("UPTIME", {"uptime"});
DumpBlockStatFiles();
- dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
DumpFile("MEMORY INFO", "/proc/meminfo");
RunCommand("CPU INFO", {"top", "-b", "-n", "1", "-H", "-s", "6", "-o",
"pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name"});
@@ -3631,110 +3630,3 @@
}
return info.st_mtime;
}
-
-void dump_emmc_ecsd(const char *ext_csd_path) {
- // List of interesting offsets
- struct hex {
- char str[2];
- };
- static const size_t EXT_CSD_REV = 192 * sizeof(hex);
- static const size_t EXT_PRE_EOL_INFO = 267 * sizeof(hex);
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268 * sizeof(hex);
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269 * sizeof(hex);
-
- std::string buffer;
- if (!android::base::ReadFileToString(ext_csd_path, &buffer)) {
- return;
- }
-
- printf("------ %s Extended CSD ------\n", ext_csd_path);
-
- if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
- return;
- }
-
- int ext_csd_rev = 0;
- std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) {
- printf("*** %s: EXT_CSD_REV parse error \"%s\"\n\n", ext_csd_path, sub.c_str());
- return;
- }
-
- static const char *ver_str[] = {
- "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
- };
- printf("rev 1.%d (MMC %s)\n", ext_csd_rev,
- (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ? ver_str[ext_csd_rev]
- : "Unknown");
- if (ext_csd_rev < 7) {
- printf("\n");
- return;
- }
-
- if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
- return;
- }
-
- int ext_pre_eol_info = 0;
- sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) {
- printf("*** %s: PRE_EOL_INFO parse error \"%s\"\n\n", ext_csd_path, sub.c_str());
- return;
- }
-
- static const char *eol_str[] = {
- "Undefined",
- "Normal",
- "Warning (consumed 80% of reserve)",
- "Urgent (consumed 90% of reserve)"
- };
- printf(
- "PRE_EOL_INFO %d (MMC %s)\n", ext_pre_eol_info,
- eol_str[(ext_pre_eol_info < (int)(sizeof(eol_str) / sizeof(eol_str[0]))) ? ext_pre_eol_info
- : 0]);
-
- for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
- lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
- lifetime += sizeof(hex)) {
- int ext_device_life_time_est;
- static const char *est_str[] = {
- "Undefined",
- "0-10% of device lifetime used",
- "10-20% of device lifetime used",
- "20-30% of device lifetime used",
- "30-40% of device lifetime used",
- "40-50% of device lifetime used",
- "50-60% of device lifetime used",
- "60-70% of device lifetime used",
- "70-80% of device lifetime used",
- "80-90% of device lifetime used",
- "90-100% of device lifetime used",
- "Exceeded the maximum estimated device lifetime",
- };
-
- if (buffer.length() < (lifetime + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n", ext_csd_path, buffer.length());
- break;
- }
-
- ext_device_life_time_est = 0;
- sub = buffer.substr(lifetime, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) {
- printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n", ext_csd_path,
- (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
- sub.c_str());
- continue;
- }
- printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
- (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
- ext_device_life_time_est,
- est_str[(ext_device_life_time_est < (int)(sizeof(est_str) / sizeof(est_str[0])))
- ? ext_device_life_time_est
- : 0]);
- }
-
- printf("\n");
-}
-
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index c059641..82bf821 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -584,9 +584,6 @@
/** Gets the last modification time of a file, or default time if file is not found. */
time_t get_mtime(int fd, time_t default_mtime);
-/* Dumps eMMC Extended CSD data. */
-void dump_emmc_ecsd(const char *ext_csd_path);
-
/** Gets command-line arguments. */
void format_args(int argc, const char *argv[], std::string *args);
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 4222e36..c4aed95 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -37,6 +37,7 @@
enabled: true,
},
double_loadable: true,
+ no_apex: true,
srcs: [
"ActivityManager.cpp",
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 9e55c2c..221c002 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -81,6 +81,24 @@
return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}
+status_t IBinder::getExtension(sp<IBinder>* out) {
+ BBinder* local = this->localBinder();
+ if (local != nullptr) {
+ *out = local->getExtension();
+ return OK;
+ }
+
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr);
+
+ Parcel data;
+ Parcel reply;
+ status_t status = transact(EXTENSION_TRANSACTION, data, &reply);
+ if (status != OK) return status;
+
+ return reply.readNullableStrongBinder(out);
+}
+
// ---------------------------------------------------------------------------
class BBinder::Extras
@@ -88,6 +106,7 @@
public:
// unlocked objects
bool mRequestingSid = false;
+ sp<IBinder> mExtension;
// for below objects
Mutex mLock;
@@ -130,6 +149,9 @@
case PING_TRANSACTION:
err = pingBinder();
break;
+ case EXTENSION_TRANSACTION:
+ err = reply->writeStrongBinder(getExtension());
+ break;
default:
err = onTransact(code, data, reply, flags);
break;
@@ -222,6 +244,17 @@
e->mRequestingSid = true;
}
+sp<IBinder> BBinder::getExtension() {
+ Extras* e = mExtras.load(std::memory_order_acquire);
+ if (e == nullptr) return nullptr;
+ return e->mExtension;
+}
+
+void BBinder::setExtension(const sp<IBinder>& extension) {
+ Extras* e = getOrCreateExtras();
+ e->mExtension = extension;
+}
+
BBinder::~BBinder()
{
Extras* e = mExtras.load(std::memory_order_relaxed);
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index dec75f5..1095c7f 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -64,6 +64,10 @@
// This must be called before the object is sent to another process. Not thread safe.
void setRequestingSid(bool requestSid);
+ sp<IBinder> getExtension();
+ // This must be called before the object is sent to another process. Not thread safe.
+ void setExtension(const sp<IBinder>& extension);
+
protected:
virtual ~BBinder();
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index aa44285..408037e 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -59,6 +59,7 @@
SHELL_COMMAND_TRANSACTION = B_PACK_CHARS('_','C','M','D'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
+ EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
@@ -86,6 +87,49 @@
Vector<String16>& args, const sp<IShellCallback>& callback,
const sp<IResultReceiver>& resultReceiver);
+ /**
+ * This allows someone to add their own additions to an interface without
+ * having to modify the original interface.
+ *
+ * For instance, imagine if we have this interface:
+ * interface IFoo { void doFoo(); }
+ *
+ * If an unrelated owner (perhaps in a downstream codebase) wants to make a
+ * change to the interface, they have two options:
+ *
+ * A). Historical option that has proven to be BAD! Only the original
+ * author of an interface should change an interface. If someone
+ * downstream wants additional functionality, they should not ever
+ * change the interface or use this method.
+ *
+ * BAD TO DO: interface IFoo { BAD TO DO
+ * BAD TO DO: void doFoo(); BAD TO DO
+ * BAD TO DO: + void doBar(); // adding a method BAD TO DO
+ * BAD TO DO: } BAD TO DO
+ *
+ * B). Option that this method enables!
+ * Leave the original interface unchanged (do not change IFoo!).
+ * Instead, create a new interface in a downstream package:
+ *
+ * package com.<name>; // new functionality in a new package
+ * interface IBar { void doBar(); }
+ *
+ * When registering the interface, add:
+ * sp<MyFoo> foo = new MyFoo; // class in AOSP codebase
+ * sp<MyBar> bar = new MyBar; // custom extension class
+ * foo->setExtension(bar); // use method in BBinder
+ *
+ * Then, clients of IFoo can get this extension:
+ * sp<IBinder> binder = ...;
+ * sp<IFoo> foo = interface_cast<IFoo>(binder); // handle if null
+ * sp<IBinder> barBinder;
+ * ... handle error ... = binder->getExtension(&barBinder);
+ * sp<IBar> bar = interface_cast<IBar>(barBinder);
+ * // if bar is null, then there is no extension or a different
+ * // type of extension
+ */
+ status_t getExtension(sp<IBinder>* out);
+
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t transact( uint32_t code,
const Parcel& data,
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index bd6886d..b06ca86 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -589,3 +589,40 @@
recipient->decStrong(nullptr);
}
+
+binder_status_t AIBinder_getExtension(AIBinder* binder, AIBinder** outExt) {
+ if (binder == nullptr || outExt == nullptr) {
+ if (outExt != nullptr) {
+ *outExt = nullptr;
+ }
+ return STATUS_UNEXPECTED_NULL;
+ }
+
+ sp<IBinder> ext;
+ status_t res = binder->getBinder()->getExtension(&ext);
+
+ if (res != android::OK) {
+ *outExt = nullptr;
+ return PruneStatusT(res);
+ }
+
+ sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(ext);
+ if (ret != nullptr) ret->incStrong(binder);
+
+ *outExt = ret.get();
+ return STATUS_OK;
+}
+
+binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) {
+ if (binder == nullptr || ext == nullptr) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+
+ ABBinder* rawBinder = binder->asABBinder();
+ if (rawBinder == nullptr) {
+ return STATUS_INVALID_OPERATION;
+ }
+
+ rawBinder->setExtension(ext->getBinder());
+ return STATUS_OK;
+}
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 80d1254..160739b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -510,6 +510,76 @@
void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) __INTRODUCED_IN(29);
#endif //__ANDROID_API__ >= __ANDROID_API_Q__
+
+#if __ANDROID_API__ >= __ANDROID_API_R__
+
+/**
+ * Gets the extension registered with AIBinder_setExtension.
+ *
+ * See AIBinder_setExtension.
+ *
+ * \param binder the object to get the extension of.
+ * \param outExt the returned extension object. Will be null if there is no extension set or
+ * non-null with one strong ref count.
+ *
+ * \return error of getting the interface (may be a transaction error if this is
+ * remote binder). STATUS_UNEXPECTED_NULL if binder is null.
+ */
+binder_status_t AIBinder_getExtension(AIBinder* binder, AIBinder** outExt) __INTRODUCED_IN(30);
+
+/**
+ * Gets the extension of a binder interface. This allows a downstream developer to add
+ * an extension to an interface without modifying its interface file. This should be
+ * called immediately when the object is created before it is passed to another thread.
+ * No thread safety is required.
+ *
+ * For instance, imagine if we have this interface:
+ * interface IFoo { void doFoo(); }
+ *
+ * A). Historical option that has proven to be BAD! Only the original
+ * author of an interface should change an interface. If someone
+ * downstream wants additional functionality, they should not ever
+ * change the interface or use this method.
+ *
+ * BAD TO DO: interface IFoo { BAD TO DO
+ * BAD TO DO: void doFoo(); BAD TO DO
+ * BAD TO DO: + void doBar(); // adding a method BAD TO DO
+ * BAD TO DO: } BAD TO DO
+ *
+ * B). Option that this method enables.
+ * Leave the original interface unchanged (do not change IFoo!).
+ * Instead, create a new interface in a downstream package:
+ *
+ * package com.<name>; // new functionality in a new package
+ * interface IBar { void doBar(); }
+ *
+ * When registering the interface, add:
+ * std::shared_ptr<MyFoo> foo = new MyFoo; // class in AOSP codebase
+ * std::shared_ptr<MyBar> bar = new MyBar; // custom extension class
+ * ... = AIBinder_setExtension(foo->asBinder().get(), bar->asBinder().get());
+ * // handle error
+ *
+ * Then, clients of IFoo can get this extension:
+ * SpAIBinder binder = ...;
+ * std::shared_ptr<IFoo> foo = IFoo::fromBinder(binder); // handle if null
+ * SpAIBinder barBinder;
+ * ... = AIBinder_getExtension(barBinder.get());
+ * // handle error
+ * std::shared_ptr<IBar> bar = IBar::fromBinder(barBinder);
+ * // type is checked with AIBinder_associateClass
+ * // if bar is null, then there is no extension or a different
+ * // type of extension
+ *
+ * \param binder the object to get the extension on. Must be local.
+ * \param ext the extension to set (binder will hold a strong reference to this)
+ *
+ * \return OK on success, STATUS_INVALID_OPERATION if binder is not local, STATUS_UNEXPECTED_NULL
+ * if either binder is null.
+ */
+binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) __INTRODUCED_IN(30);
+
+#endif //__ANDROID_API__ >= __ANDROID_API_R__
+
__END_DECLS
/** @} */
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index feedde6..d4d5387 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -101,6 +101,9 @@
LIBBINDER_NDK30 { # introduced=30
global:
+ AIBinder_getExtension;
+ AIBinder_setExtension;
+
AIBinder_markSystemStability; # apex
AIBinder_markVendorStability; # vndk
AIBinder_markVintfStability; # apex vndk
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 4f0c969..5f8887b 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -766,6 +766,24 @@
EXPECT_TRUE(strong_from_weak == nullptr);
}
+TEST_F(BinderLibTest, LocalGetExtension) {
+ sp<BBinder> binder = new BBinder();
+ sp<IBinder> ext = new BBinder();
+ binder->setExtension(ext);
+ EXPECT_EQ(ext, binder->getExtension());
+}
+
+TEST_F(BinderLibTest, RemoteGetExtension) {
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != nullptr);
+
+ sp<IBinder> extension;
+ EXPECT_EQ(NO_ERROR, server->getExtension(&extension));
+ ASSERT_NE(nullptr, extension.get());
+
+ EXPECT_EQ(NO_ERROR, extension->pingBinder());
+}
+
TEST_F(BinderLibTest, CheckHandleZeroBinderHighBitsZeroCookie) {
status_t ret;
Parcel data, reply;
@@ -1170,6 +1188,13 @@
BinderLibTestService* testServicePtr;
{
sp<BinderLibTestService> testService = new BinderLibTestService(index);
+
+ /*
+ * Normally would also contain functionality as well, but we are only
+ * testing the extension mechanism.
+ */
+ testService->setExtension(new BBinder());
+
/*
* We need this below, but can't hold a sp<> because it prevents the
* node from being cleaned up automatically. It's safe in this case
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 3db8a39..bb5c151 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1306,7 +1306,7 @@
bool active = swapchain->surface.swapchain_handle == swapchain_handle;
ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr;
- if (swapchain->frame_timestamps_enabled) {
+ if (window && swapchain->frame_timestamps_enabled) {
native_window_enable_frame_timestamps(window, false);
}
for (uint32_t i = 0; i < swapchain->num_images; i++)