summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/am/src/com/android/commands/am/Instrument.java3
-rw-r--r--cmds/bootanimation/BootAnimation.cpp23
-rw-r--r--cmds/bootanimation/FORMAT.md1
-rw-r--r--cmds/idmap2/Android.bp4
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.cpp8
-rw-r--r--cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl2
-rw-r--r--cmds/idmap2/include/idmap2/FabricatedOverlay.h19
-rw-r--r--cmds/idmap2/include/idmap2/ResourceContainer.h2
-rw-r--r--cmds/idmap2/include/idmap2/ResourceMapping.h3
-rw-r--r--cmds/idmap2/include/idmap2/ResourceUtils.h6
-rw-r--r--cmds/idmap2/libidmap2/FabricatedOverlay.cpp147
-rw-r--r--cmds/idmap2/libidmap2/ResourceContainer.cpp6
-rw-r--r--cmds/idmap2/libidmap2/ResourceMapping.cpp6
-rw-r--r--cmds/idmap2/libidmap2/proto/fabricated_v1.proto1
-rw-r--r--cmds/idmap2/tests/FabricatedOverlayTests.cpp73
-rw-r--r--cmds/idmap2/tests/IdmapTests.cpp14
-rw-r--r--cmds/idmap2/tests/R.h1
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp12
-rw-r--r--cmds/idmap2/tests/ResultTests.cpp5
-rw-r--r--cmds/telecom/src/com/android/commands/telecom/Telecom.java12
-rw-r--r--cmds/uinput/jni/com_android_commands_uinput_Device.cpp12
-rw-r--r--cmds/uinput/jni/com_android_commands_uinput_Device.h1
-rw-r--r--cmds/uinput/src/com/android/commands/uinput/Device.java11
-rw-r--r--cmds/uinput/src/com/android/commands/uinput/Event.java23
-rw-r--r--cmds/uinput/src/com/android/commands/uinput/Uinput.java2
25 files changed, 272 insertions, 125 deletions
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 7ff4bc4bcf76..2604497dcb63 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -425,7 +425,8 @@ public class Instrument {
if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
return cn;
} else {
- List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
+ List<InstrumentationInfo> infos = mPm.queryInstrumentationAsUser(
+ null, 0, userId).getList();
final int numInfos = infos == null ? 0: infos.size();
ArrayList<ComponentName> cns = new ArrayList<>();
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 33739f39aaa4..814800bcd9e5 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -71,8 +71,6 @@ static const char PRODUCT_BOOTANIMATION_DARK_FILE[] = "/product/media/bootanimat
static const char PRODUCT_BOOTANIMATION_FILE[] = "/product/media/bootanimation.zip";
static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";
static const char APEX_BOOTANIMATION_FILE[] = "/apex/com.android.bootanimation/etc/bootanimation.zip";
-static const char PRODUCT_ENCRYPTED_BOOTANIMATION_FILE[] = "/product/media/bootanimation-encrypted.zip";
-static const char SYSTEM_ENCRYPTED_BOOTANIMATION_FILE[] = "/system/media/bootanimation-encrypted.zip";
static const char OEM_SHUTDOWNANIMATION_FILE[] = "/oem/media/shutdownanimation.zip";
static const char PRODUCT_SHUTDOWNANIMATION_FILE[] = "/product/media/shutdownanimation.zip";
static const char SYSTEM_SHUTDOWNANIMATION_FILE[] = "/system/media/shutdownanimation.zip";
@@ -617,10 +615,6 @@ void BootAnimation::resizeSurface(int newWidth, int newHeight) {
mWidth = limitedSize.width;
mHeight = limitedSize.height;
- SurfaceComposerClient::Transaction t;
- t.setSize(mFlingerSurfaceControl, mWidth, mHeight);
- t.apply();
-
EGLConfig config = getEglConfig(mDisplay);
EGLSurface surface = eglCreateWindowSurface(mDisplay, config, mFlingerSurface.get(), nullptr);
if (eglMakeCurrent(mDisplay, surface, surface, mContext) == EGL_FALSE) {
@@ -654,23 +648,6 @@ bool BootAnimation::findBootAnimationFileInternal(const std::vector<std::string>
}
void BootAnimation::findBootAnimationFile() {
- // If the device has encryption turned on or is in process
- // of being encrypted we show the encrypted boot animation.
- char decrypt[PROPERTY_VALUE_MAX];
- property_get("vold.decrypt", decrypt, "");
-
- bool encryptedAnimation = atoi(decrypt) != 0 ||
- !strcmp("trigger_restart_min_framework", decrypt);
-
- if (!mShuttingDown && encryptedAnimation) {
- static const std::vector<std::string> encryptedBootFiles = {
- PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE,
- };
- if (findBootAnimationFileInternal(encryptedBootFiles)) {
- return;
- }
- }
-
const bool playDarkAnim = android::base::GetIntProperty("ro.boot.theme", 0) == 1;
static const std::vector<std::string> bootFiles = {
APEX_BOOTANIMATION_FILE, playDarkAnim ? PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE,
diff --git a/cmds/bootanimation/FORMAT.md b/cmds/bootanimation/FORMAT.md
index 64814c8a25e2..988685e23443 100644
--- a/cmds/bootanimation/FORMAT.md
+++ b/cmds/bootanimation/FORMAT.md
@@ -4,7 +4,6 @@
The system selects a boot animation zipfile from the following locations, in order:
- /system/media/bootanimation-encrypted.zip (if getprop("vold.decrypt") = '1')
/system/media/bootanimation.zip
/oem/media/bootanimation.zip
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 6ef6845c75f2..18ec5a407b24 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -23,6 +23,7 @@ package {
cc_defaults {
name: "idmap2_defaults",
+ cpp_std: "gnu++2b",
tidy: true,
tidy_checks: [
"modernize-*",
@@ -31,6 +32,7 @@ cc_defaults {
"android-*",
"misc-*",
"readability-*",
+ "-readability-identifier-length",
],
tidy_checks_as_errors: [
"modernize-*",
@@ -54,7 +56,6 @@ cc_defaults {
"-readability-convert-member-functions-to-static",
"-readability-duplicate-include",
"-readability-else-after-return",
- "-readability-identifier-length",
"-readability-named-parameter",
"-readability-redundant-access-specifiers",
"-readability-uppercase-literal-suffix",
@@ -115,6 +116,7 @@ cc_library {
"libidmap2/proto/*.proto",
],
host_supported: true,
+ tidy: false,
proto: {
type: "lite",
export_proto_headers: true,
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index 1b2d905aec0a..083bbf01bf5b 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -234,7 +234,13 @@ Status Idmap2Service::createFabricatedOverlay(
}
for (const auto& res : overlay.entries) {
- builder.SetResourceValue(res.resourceName, res.dataType, res.data);
+ if (res.dataType == Res_value::TYPE_STRING) {
+ builder.SetResourceValue(res.resourceName, res.dataType, res.stringData.value(),
+ res.configuration.value_or(std::string()));
+ } else {
+ builder.SetResourceValue(res.resourceName, res.dataType, res.data,
+ res.configuration.value_or(std::string()));
+ }
}
// Generate the file path of the fabricated overlay and ensure it does not collide with an
diff --git a/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl b/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl
index 6c2af274ae32..c773e112997d 100644
--- a/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl
+++ b/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl
@@ -23,4 +23,6 @@ parcelable FabricatedOverlayInternalEntry {
@utf8InCpp String resourceName;
int dataType;
int data;
+ @nullable @utf8InCpp String stringData;
+ @nullable @utf8InCpp String configuration;
} \ No newline at end of file
diff --git a/cmds/idmap2/include/idmap2/FabricatedOverlay.h b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
index 375671881e5f..05b0618131c9 100644
--- a/cmds/idmap2/include/idmap2/FabricatedOverlay.h
+++ b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
@@ -39,7 +39,11 @@ struct FabricatedOverlay {
Builder& SetOverlayable(const std::string& name);
Builder& SetResourceValue(const std::string& resource_name, uint8_t data_type,
- uint32_t data_value);
+ uint32_t data_value, const std::string& configuration);
+
+ Builder& SetResourceValue(const std::string& resource_name, uint8_t data_type,
+ const std::string& data_string_value,
+ const std::string& configuration);
WARN_UNUSED Result<FabricatedOverlay> Build();
@@ -48,6 +52,8 @@ struct FabricatedOverlay {
std::string resource_name;
DataType data_type;
DataValue data_value;
+ std::string data_string_value;
+ std::string configuration;
};
std::string package_name_;
@@ -62,18 +68,21 @@ struct FabricatedOverlay {
private:
struct SerializedData {
- std::unique_ptr<uint8_t[]> data;
- size_t data_size;
- uint32_t crc;
- };
+ std::unique_ptr<uint8_t[]> pb_data;
+ size_t pb_data_size;
+ uint32_t pb_crc;
+ std::string sp_data;
+ };
Result<SerializedData*> InitializeData() const;
Result<uint32_t> GetCrc() const;
explicit FabricatedOverlay(pb::FabricatedOverlay&& overlay,
+ std::string&& string_pool_data_,
std::optional<uint32_t> crc_from_disk = {});
pb::FabricatedOverlay overlay_pb_;
+ std::string string_pool_data_;
std::optional<uint32_t> crc_from_disk_;
mutable std::optional<SerializedData> data_;
diff --git a/cmds/idmap2/include/idmap2/ResourceContainer.h b/cmds/idmap2/include/idmap2/ResourceContainer.h
index c3ba4640bd77..2452ff0784ce 100644
--- a/cmds/idmap2/include/idmap2/ResourceContainer.h
+++ b/cmds/idmap2/include/idmap2/ResourceContainer.h
@@ -66,7 +66,7 @@ struct OverlayData {
struct Value {
std::string resource_name;
- std::variant<ResourceIdValue, TargetValue> value;
+ std::variant<ResourceIdValue, TargetValueWithConfig> value;
};
struct InlineStringPoolData {
diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h
index 5a0a384f75a3..21862a3635d5 100644
--- a/cmds/idmap2/include/idmap2/ResourceMapping.h
+++ b/cmds/idmap2/include/idmap2/ResourceMapping.h
@@ -69,7 +69,8 @@ class ResourceMapping {
// If `allow_rewriting_` is true, then the overlay-to-target map will be populated if the target
// resource id is mapped to an overlay resource id.
Result<Unit> AddMapping(ResourceId target_resource,
- const std::variant<OverlayData::ResourceIdValue, TargetValue>& value);
+ const std::variant<OverlayData::ResourceIdValue,
+ TargetValueWithConfig>& value);
TargetResourceMap target_map_;
OverlayResourceMap overlay_map_;
diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h
index a0202dfee473..8ec749602c4a 100644
--- a/cmds/idmap2/include/idmap2/ResourceUtils.h
+++ b/cmds/idmap2/include/idmap2/ResourceUtils.h
@@ -40,6 +40,12 @@ using DataValue = uint32_t; // Res_value::data
struct TargetValue {
DataType data_type;
DataValue data_value;
+ std::string data_string_value;
+};
+
+struct TargetValueWithConfig {
+ TargetValue value;
+ std::string config;
};
namespace utils {
diff --git a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
index 8352dbb7b619..bde9b0be4361 100644
--- a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
+++ b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
@@ -17,8 +17,9 @@
#include "idmap2/FabricatedOverlay.h"
#include <androidfw/ResourceUtils.h>
+#include <androidfw/StringPool.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <utils/ByteOrder.h>
#include <zlib.h>
@@ -30,6 +31,8 @@
namespace android::idmap2 {
+constexpr auto kBufferSize = 1024;
+
namespace {
bool Read32(std::istream& stream, uint32_t* out) {
uint32_t value;
@@ -47,8 +50,11 @@ void Write32(std::ostream& stream, uint32_t value) {
} // namespace
FabricatedOverlay::FabricatedOverlay(pb::FabricatedOverlay&& overlay,
+ std::string&& string_pool_data,
std::optional<uint32_t> crc_from_disk)
- : overlay_pb_(std::forward<pb::FabricatedOverlay>(overlay)), crc_from_disk_(crc_from_disk) {
+ : overlay_pb_(std::forward<pb::FabricatedOverlay>(overlay)),
+ string_pool_data_(std::move(string_pool_data)),
+ crc_from_disk_(crc_from_disk) {
}
FabricatedOverlay::Builder::Builder(const std::string& package_name, const std::string& name,
@@ -64,13 +70,26 @@ FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetOverlayable(const std
}
FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue(
- const std::string& resource_name, uint8_t data_type, uint32_t data_value) {
- entries_.emplace_back(Entry{resource_name, data_type, data_value});
+ const std::string& resource_name, uint8_t data_type, uint32_t data_value,
+ const std::string& configuration) {
+ entries_.emplace_back(Entry{resource_name, data_type, data_value, "", configuration});
+ return *this;
+}
+
+FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue(
+ const std::string& resource_name, uint8_t data_type, const std::string& data_string_value,
+ const std::string& configuration) {
+ entries_.emplace_back(Entry{resource_name, data_type, 0, data_string_value, configuration});
return *this;
}
Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
- std::map<std::string, std::map<std::string, std::map<std::string, TargetValue>>> entries;
+ using ConfigMap = std::map<std::string, TargetValue>;
+ using EntryMap = std::map<std::string, ConfigMap>;
+ using TypeMap = std::map<std::string, EntryMap>;
+ using PackageMap = std::map<std::string, TypeMap>;
+ PackageMap package_map;
+ android::StringPool string_pool;
for (const auto& res_entry : entries_) {
StringPiece package_substr;
StringPiece type_name;
@@ -90,11 +109,10 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
return Error("resource name '%s' missing entry name", res_entry.resource_name.c_str());
}
- auto package = entries.find(package_name);
- if (package == entries.end()) {
- package = entries
- .insert(std::make_pair(
- package_name, std::map<std::string, std::map<std::string, TargetValue>>()))
+ auto package = package_map.find(package_name);
+ if (package == package_map.end()) {
+ package = package_map
+ .insert(std::make_pair(package_name, TypeMap()))
.first;
}
@@ -102,16 +120,22 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
if (type == package->second.end()) {
type =
package->second
- .insert(std::make_pair(type_name.to_string(), std::map<std::string, TargetValue>()))
+ .insert(std::make_pair(type_name.to_string(), EntryMap()))
.first;
}
auto entry = type->second.find(entry_name.to_string());
if (entry == type->second.end()) {
- entry = type->second.insert(std::make_pair(entry_name.to_string(), TargetValue())).first;
+ entry = type->second.insert(std::make_pair(entry_name.to_string(), ConfigMap())).first;
}
- entry->second = TargetValue{res_entry.data_type, res_entry.data_value};
+ auto value = entry->second.find(res_entry.configuration);
+ if (value == entry->second.end()) {
+ value = entry->second.insert(std::make_pair(res_entry.configuration, TargetValue())).first;
+ }
+
+ value->second = TargetValue{res_entry.data_type, res_entry.data_value,
+ res_entry.data_string_value};
}
pb::FabricatedOverlay overlay_pb;
@@ -120,25 +144,35 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
overlay_pb.set_target_package_name(target_package_name_);
overlay_pb.set_target_overlayable(target_overlayable_);
- for (const auto& package : entries) {
+ for (auto& package : package_map) {
auto package_pb = overlay_pb.add_packages();
package_pb->set_name(package.first);
- for (const auto& type : package.second) {
+ for (auto& type : package.second) {
auto type_pb = package_pb->add_types();
type_pb->set_name(type.first);
- for (const auto& entry : type.second) {
- auto entry_pb = type_pb->add_entries();
- entry_pb->set_name(entry.first);
- pb::ResourceValue* value = entry_pb->mutable_res_value();
- value->set_data_type(entry.second.data_type);
- value->set_data_value(entry.second.data_value);
+ for (auto& entry : type.second) {
+ for (const auto& value: entry.second) {
+ auto entry_pb = type_pb->add_entries();
+ entry_pb->set_name(entry.first);
+ entry_pb->set_configuration(value.first);
+ pb::ResourceValue* pb_value = entry_pb->mutable_res_value();
+ pb_value->set_data_type(value.second.data_type);
+ if (value.second.data_type == Res_value::TYPE_STRING) {
+ auto ref = string_pool.MakeRef(value.second.data_string_value);
+ pb_value->set_data_value(ref.index());
+ } else {
+ pb_value->set_data_value(value.second.data_value);
+ }
+ }
}
}
}
- return FabricatedOverlay(std::move(overlay_pb));
+ android::BigBuffer string_buffer(kBufferSize);
+ android::StringPool::FlattenUtf8(&string_buffer, string_pool, nullptr);
+ return FabricatedOverlay(std::move(overlay_pb), string_buffer.to_string());
}
Result<FabricatedOverlay> FabricatedOverlay::FromBinaryStream(std::istream& stream) {
@@ -156,48 +190,67 @@ Result<FabricatedOverlay> FabricatedOverlay::FromBinaryStream(std::istream& stre
return Error("Failed to read fabricated overlay version.");
}
- if (version != 1) {
+ if (version != 1 && version != 2) {
return Error("Invalid fabricated overlay version '%u'.", version);
}
uint32_t crc;
if (!Read32(stream, &crc)) {
- return Error("Failed to read fabricated overlay version.");
+ return Error("Failed to read fabricated overlay crc.");
}
pb::FabricatedOverlay overlay{};
- if (!overlay.ParseFromIstream(&stream)) {
- return Error("Failed read fabricated overlay proto.");
+ std::string sp_data;
+ if (version == 2) {
+ uint32_t sp_size;
+ if (!Read32(stream, &sp_size)) {
+ return Error("Failed read string pool size.");
+ }
+ std::string buf(sp_size, '\0');
+ if (!stream.read(buf.data(), sp_size)) {
+ return Error("Failed to read string pool.");
+ }
+ sp_data = buf;
+
+ if (!overlay.ParseFromIstream(&stream)) {
+ return Error("Failed read fabricated overlay proto.");
+ }
+ } else {
+ if (!overlay.ParseFromIstream(&stream)) {
+ return Error("Failed read fabricated overlay proto.");
+ }
}
// If the proto version is the latest version, then the contents of the proto must be the same
// when the proto is re-serialized; otherwise, the crc must be calculated because migrating the
// proto to the latest version will likely change the contents of the fabricated overlay.
- return FabricatedOverlay(std::move(overlay), version == kFabricatedOverlayCurrentVersion
+ return FabricatedOverlay(std::move(overlay), std::move(sp_data),
+ version == kFabricatedOverlayCurrentVersion
? std::optional<uint32_t>(crc)
: std::nullopt);
}
Result<FabricatedOverlay::SerializedData*> FabricatedOverlay::InitializeData() const {
if (!data_.has_value()) {
- auto size = overlay_pb_.ByteSizeLong();
- auto data = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
+ auto pb_size = overlay_pb_.ByteSizeLong();
+ auto pb_data = std::unique_ptr<uint8_t[]>(new uint8_t[pb_size]);
// Ensure serialization is deterministic
- google::protobuf::io::ArrayOutputStream array_stream(data.get(), size);
+ google::protobuf::io::ArrayOutputStream array_stream(pb_data.get(), pb_size);
google::protobuf::io::CodedOutputStream output_stream(&array_stream);
output_stream.SetSerializationDeterministic(true);
overlay_pb_.SerializeWithCachedSizes(&output_stream);
- if (output_stream.HadError() || size != output_stream.ByteCount()) {
+ if (output_stream.HadError() || pb_size != output_stream.ByteCount()) {
return Error("Failed to serialize fabricated overlay.");
}
// Calculate the crc using the proto data and the version.
- uint32_t crc = crc32(0L, Z_NULL, 0);
- crc = crc32(crc, reinterpret_cast<const uint8_t*>(&kFabricatedOverlayCurrentVersion),
+ uint32_t pb_crc = crc32(0L, Z_NULL, 0);
+ pb_crc = crc32(pb_crc, reinterpret_cast<const uint8_t*>(&kFabricatedOverlayCurrentVersion),
sizeof(uint32_t));
- crc = crc32(crc, data.get(), size);
- data_ = SerializedData{std::move(data), size, crc};
+ pb_crc = crc32(pb_crc, pb_data.get(), pb_size);
+
+ data_ = SerializedData{std::move(pb_data), pb_size, pb_crc, string_pool_data_};
}
return &(*data_);
}
@@ -209,7 +262,7 @@ Result<uint32_t> FabricatedOverlay::GetCrc() const {
if (!data) {
return data.GetError();
}
- return (*data)->crc;
+ return (*data)->pb_crc;
}
Result<Unit> FabricatedOverlay::ToBinaryStream(std::ostream& stream) const {
@@ -220,8 +273,13 @@ Result<Unit> FabricatedOverlay::ToBinaryStream(std::ostream& stream) const {
Write32(stream, kFabricatedOverlayMagic);
Write32(stream, kFabricatedOverlayCurrentVersion);
- Write32(stream, (*data)->crc);
- stream.write(reinterpret_cast<const char*>((*data)->data.get()), (*data)->data_size);
+ Write32(stream, (*data)->pb_crc);
+ Write32(stream, (*data)->sp_data.length());
+ stream.write((*data)->sp_data.data(), (*data)->sp_data.length());
+ if (stream.bad()) {
+ return Error("Failed to write string pool data.");
+ }
+ stream.write(reinterpret_cast<const char*>((*data)->pb_data.get()), (*data)->pb_data_size);
if (stream.bad()) {
return Error("Failed to write serialized fabricated overlay.");
}
@@ -283,11 +341,20 @@ Result<OverlayData> FabContainer::GetOverlayData(const OverlayManifestInfo& info
entry.name().c_str());
const auto& res_value = entry.res_value();
result.pairs.emplace_back(OverlayData::Value{
- name, TargetValue{.data_type = static_cast<uint8_t>(res_value.data_type()),
- .data_value = res_value.data_value()}});
+ name, TargetValueWithConfig{.config = entry.configuration(), .value = TargetValue{
+ .data_type = static_cast<uint8_t>(res_value.data_type()),
+ .data_value = res_value.data_value()}}});
}
}
}
+ const uint32_t string_pool_data_length = overlay_.string_pool_data_.length();
+ result.string_pool_data = OverlayData::InlineStringPoolData{
+ .data = std::unique_ptr<uint8_t[]>(new uint8_t[string_pool_data_length]),
+ .data_length = string_pool_data_length,
+ .string_pool_offset = 0,
+ };
+ memcpy(result.string_pool_data->data.get(), overlay_.string_pool_data_.data(),
+ string_pool_data_length);
return result;
}
diff --git a/cmds/idmap2/libidmap2/ResourceContainer.cpp b/cmds/idmap2/libidmap2/ResourceContainer.cpp
index a62472c8f11e..0e3590486c6f 100644
--- a/cmds/idmap2/libidmap2/ResourceContainer.cpp
+++ b/cmds/idmap2/libidmap2/ResourceContainer.cpp
@@ -226,8 +226,10 @@ Result<OverlayData> CreateResourceMapping(ResourceId id, const ZipAssetsProvider
*target_resource, OverlayData::ResourceIdValue{overlay_resource->data, rewrite_id}});
} else {
overlay_data.pairs.emplace_back(
- OverlayData::Value{*target_resource, TargetValue{.data_type = overlay_resource->dataType,
- .data_value = overlay_resource->data}});
+ OverlayData::Value{*target_resource, TargetValueWithConfig{
+ .config = std::string(),
+ .value = TargetValue{.data_type = overlay_resource->dataType,
+ .data_value = overlay_resource->data}}});
}
}
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 3bbbf248c87d..8ebe5aa46e73 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -160,7 +160,7 @@ Result<ResourceMapping> ResourceMapping::FromContainers(const TargetResourceCont
Result<Unit> ResourceMapping::AddMapping(
ResourceId target_resource,
- const std::variant<OverlayData::ResourceIdValue, TargetValue>& value) {
+ const std::variant<OverlayData::ResourceIdValue, TargetValueWithConfig>& value) {
if (target_map_.find(target_resource) != target_map_.end()) {
return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
}
@@ -176,8 +176,8 @@ Result<Unit> ResourceMapping::AddMapping(
overlay_map_.insert(std::make_pair(overlay_resource->overlay_id, target_resource));
}
} else {
- auto overlay_value = std::get<TargetValue>(value);
- target_map_.insert(std::make_pair(target_resource, overlay_value));
+ auto overlay_value = std::get<TargetValueWithConfig>(value);
+ target_map_.insert(std::make_pair(target_resource, overlay_value.value));
}
return Unit{};
diff --git a/cmds/idmap2/libidmap2/proto/fabricated_v1.proto b/cmds/idmap2/libidmap2/proto/fabricated_v1.proto
index a392b2b6d856..c7a79b31e151 100644
--- a/cmds/idmap2/libidmap2/proto/fabricated_v1.proto
+++ b/cmds/idmap2/libidmap2/proto/fabricated_v1.proto
@@ -46,6 +46,7 @@ message ResourceEntry {
oneof value {
ResourceValue res_value = 2;
}
+ string configuration = 3;
}
message ResourceValue {
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index 468ea0c634c1..e804c879ee82 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -43,9 +43,17 @@ TEST(FabricatedOverlayTests, OverlayInfo) {
TEST(FabricatedOverlayTests, SetResourceValue) {
auto overlay =
FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
- .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
- .SetResourceValue("com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U)
- .SetResourceValue("string/int3", Res_value::TYPE_REFERENCE, 0x7f010000)
+ .SetResourceValue(
+ "com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "port")
+ .SetResourceValue(
+ "com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U, "land")
+ .SetResourceValue(
+ "string/int3", Res_value::TYPE_REFERENCE, 0x7f010000, "xxhdpi-v7")
+ .SetResourceValue(
+ "com.example.target:string/string1",
+ Res_value::TYPE_STRING,
+ "foobar",
+ "en-rUS-normal-xxhdpi-v21")
.Build();
ASSERT_TRUE(overlay);
auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
@@ -59,42 +67,54 @@ TEST(FabricatedOverlayTests, SetResourceValue) {
auto pairs = container->GetOverlayData(*info);
ASSERT_TRUE(pairs);
- EXPECT_FALSE(pairs->string_pool_data.has_value());
- ASSERT_EQ(3U, pairs->pairs.size());
+ ASSERT_EQ(4U, pairs->pairs.size());
+ auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
+ pairs->string_pool_data->data_length, false);
auto& it = pairs->pairs[0];
ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
- auto entry = std::get_if<TargetValue>(&it.value);
+ auto entry = std::get_if<TargetValueWithConfig>(&it.value);
ASSERT_NE(nullptr, entry);
- ASSERT_EQ(1U, entry->data_value);
- ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
+ ASSERT_EQ(1U, entry->value.data_value);
+ ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
+ ASSERT_EQ("port", entry->config);
it = pairs->pairs[1];
ASSERT_EQ("com.example.target:string/int3", it.resource_name);
- entry = std::get_if<TargetValue>(&it.value);
+ entry = std::get_if<TargetValueWithConfig>(&it.value);
ASSERT_NE(nullptr, entry);
- ASSERT_EQ(0x7f010000, entry->data_value);
- ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->data_type);
+ ASSERT_EQ(0x7f010000, entry->value.data_value);
+ ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->value.data_type);
+ ASSERT_EQ("xxhdpi-v7", entry->config);
it = pairs->pairs[2];
+ ASSERT_EQ("com.example.target:string/string1", it.resource_name);
+ entry = std::get_if<TargetValueWithConfig>(&it.value);
+ ASSERT_NE(nullptr, entry);
+ ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
+ ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
+ ASSERT_EQ("en-rUS-normal-xxhdpi-v21", entry->config);
+
+ it = pairs->pairs[3];
ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
- entry = std::get_if<TargetValue>(&it.value);
+ entry = std::get_if<TargetValueWithConfig>(&it.value);
ASSERT_NE(nullptr, entry);
- ASSERT_EQ(2U, entry->data_value);
- ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
+ ASSERT_EQ(2U, entry->value.data_value);
+ ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
+ ASSERT_EQ("land", entry->config);
}
TEST(FabricatedOverlayTests, SetResourceValueBadArgs) {
{
auto builder =
FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
- .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U);
+ .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U, "");
ASSERT_FALSE(builder.Build());
}
{
auto builder =
FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
- .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U);
+ .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U, "");
ASSERT_FALSE(builder.Build());
}
}
@@ -103,7 +123,9 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
auto overlay =
FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
.SetOverlayable("TestResources")
- .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
+ .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "")
+ .SetResourceValue(
+ "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
.Build();
ASSERT_TRUE(overlay);
TemporaryFile tf;
@@ -126,14 +148,23 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
auto pairs = (*container)->GetOverlayData(*info);
ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
- EXPECT_EQ(1U, pairs->pairs.size());
+ EXPECT_EQ(2U, pairs->pairs.size());
+ auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
+ pairs->string_pool_data->data_length, false);
auto& it = pairs->pairs[0];
ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
- auto entry = std::get_if<TargetValue>(&it.value);
+ auto entry = std::get_if<TargetValueWithConfig>(&it.value);
+ ASSERT_NE(nullptr, entry);
+ EXPECT_EQ(1U, entry->value.data_value);
+ EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
+
+ it = pairs->pairs[1];
+ ASSERT_EQ("com.example.target:string/string1", it.resource_name);
+ entry = std::get_if<TargetValueWithConfig>(&it.value);
ASSERT_NE(nullptr, entry);
- EXPECT_EQ(1U, entry->data_value);
- EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
+ ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
+ ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 738b9cf237c9..ee9a424b3050 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -261,8 +261,9 @@ TEST(IdmapTests, FabricatedOverlay) {
auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target")
.SetOverlayable("TestResources")
- .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U)
- .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000)
+ .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "")
+ .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "")
+ .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "")
.Build();
ASSERT_TRUE(frro);
@@ -288,12 +289,19 @@ TEST(IdmapTests, FabricatedOverlay) {
ASSERT_EQ(data->GetTargetEntries().size(), 0U);
ASSERT_EQ(data->GetOverlayEntries().size(), 0U);
+ auto string_pool_data = data->GetStringPoolData();
+ auto string_pool = ResStringPool(string_pool_data.data(), string_pool_data.size(), false);
+
+
const auto& target_inline_entries = data->GetTargetInlineEntries();
- ASSERT_EQ(target_inline_entries.size(), 2U);
+ ASSERT_EQ(target_inline_entries.size(), 3U);
ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
Res_value::TYPE_INT_DEC, 2U);
ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
Res_value::TYPE_REFERENCE, 0x7f010000);
+ ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2,
+ Res_value::TYPE_STRING,
+ (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1));
}
TEST(IdmapTests, FailCreateIdmapInvalidName) {
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index 89219c9c8213..ad998b9a7a4c 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -41,6 +41,7 @@ namespace R::target {
constexpr ResourceId policy_system = 0x7f02000c;
constexpr ResourceId policy_system_vendor = 0x7f02000d;
constexpr ResourceId str1 = 0x7f02000e;
+ constexpr ResourceId str2 = 0x7f02000f;
constexpr ResourceId str3 = 0x7f020010;
constexpr ResourceId str4 = 0x7f020011;
} // namespace string
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 32b3d1326d92..ca9a444bcb05 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -194,8 +194,9 @@ TEST(ResourceMappingTests, InlineResources) {
TEST(ResourceMappingTests, FabricatedOverlay) {
auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target")
.SetOverlayable("TestResources")
- .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U)
- .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000)
+ .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "")
+ .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "")
+ .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "")
.Build();
ASSERT_TRUE(frro);
@@ -209,9 +210,14 @@ TEST(ResourceMappingTests, FabricatedOverlay) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U);
+ auto string_pool_data = res.GetStringPoolData();
+ auto string_pool = ResStringPool(string_pool_data.data(), string_pool_data.size(), false);
+
+ ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
ASSERT_EQ(res.GetOverlayToTargetMap().size(), 0U);
ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, 0x7f010000));
+ ASSERT_RESULT(MappingExists(res, R::target::string::str2, Res_value::TYPE_STRING,
+ (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1)));
ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_INT_DEC, 2U));
}
diff --git a/cmds/idmap2/tests/ResultTests.cpp b/cmds/idmap2/tests/ResultTests.cpp
index f2f8854cec3a..f9c4fa3c798b 100644
--- a/cmds/idmap2/tests/ResultTests.cpp
+++ b/cmds/idmap2/tests/ResultTests.cpp
@@ -259,7 +259,8 @@ TEST(ResultTests, CascadeError) {
}
struct NoCopyContainer {
- uint32_t value; // NOLINT(misc-non-private-member-variables-in-classes)
+ uint32_t value = 0; // NOLINT(misc-non-private-member-variables-in-classes)
+ NoCopyContainer() = default;
NoCopyContainer(const NoCopyContainer&) = delete;
NoCopyContainer& operator=(const NoCopyContainer&) = delete;
};
@@ -268,7 +269,7 @@ Result<std::unique_ptr<NoCopyContainer>> CreateNoCopyContainer(bool succeed) {
if (!succeed) {
return Error("foo");
}
- std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{0U});
+ std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{});
p->value = 42U;
return std::move(p);
}
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index d464e266ac36..13c7946a033f 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -54,7 +54,7 @@ public final class Telecom extends BaseCommand {
(new Telecom()).run(args);
}
-
+ private static final String CALLING_PACKAGE = Telecom.class.getPackageName();
private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled";
private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
@@ -297,7 +297,7 @@ public final class Telecom extends BaseCommand {
final String label = nextArgRequired();
PhoneAccount account = PhoneAccount.builder(handle, label)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
- mTelecomService.registerPhoneAccount(account);
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
System.out.println("Success - " + handle + " registered.");
}
@@ -327,7 +327,7 @@ public final class Telecom extends BaseCommand {
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.build();
- mTelecomService.registerPhoneAccount(account);
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
System.out.println("Success - " + handle + " registered.");
}
@@ -369,7 +369,7 @@ public final class Telecom extends BaseCommand {
private void runUnregisterPhoneAccount() throws RemoteException {
final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
- mTelecomService.unregisterPhoneAccount(handle);
+ mTelecomService.unregisterPhoneAccount(handle, CALLING_PACKAGE);
System.out.println("Success - " + handle + " unregistered.");
}
@@ -406,11 +406,11 @@ public final class Telecom extends BaseCommand {
}
private void runGetDefaultDialer() throws RemoteException {
- System.out.println(mTelecomService.getDefaultDialerPackage());
+ System.out.println(mTelecomService.getDefaultDialerPackage(CALLING_PACKAGE));
}
private void runGetSystemDialer() throws RemoteException {
- System.out.println(mTelecomService.getSystemDialerPackage());
+ System.out.println(mTelecomService.getSystemDialerPackage(CALLING_PACKAGE));
}
private void runWaitOnHandler() throws RemoteException {
diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
index 06fa2aac2c7e..3f4163dc54ec 100644
--- a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
+++ b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
@@ -99,6 +99,7 @@ JNIEnv* DeviceCallback::getJNIEnv() {
std::unique_ptr<UinputDevice> UinputDevice::open(int32_t id, const char* name, int32_t vid,
int32_t pid, uint16_t bus, uint32_t ffEffectsMax,
+ const char* port,
std::unique_ptr<DeviceCallback> callback) {
android::base::unique_fd fd(::open(UINPUT_PATH, O_RDWR | O_NONBLOCK | O_CLOEXEC));
if (!fd.ok()) {
@@ -131,6 +132,9 @@ std::unique_ptr<UinputDevice> UinputDevice::open(int32_t id, const char* name, i
return nullptr;
}
+ // set the physical port.
+ ::ioctl(fd, UI_SET_PHYS, port);
+
if (::ioctl(fd, UI_DEV_CREATE) != 0) {
ALOGE("Unable to create uinput device: %s.", strerror(errno));
return nullptr;
@@ -240,17 +244,19 @@ std::vector<int32_t> toVector(JNIEnv* env, jintArray javaArray) {
}
static jlong openUinputDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid,
- jint pid, jint bus, jint ffEffectsMax, jobject callback) {
+ jint pid, jint bus, jint ffEffectsMax, jstring rawPort,
+ jobject callback) {
ScopedUtfChars name(env, rawName);
if (name.c_str() == nullptr) {
return 0;
}
+ ScopedUtfChars port(env, rawPort);
std::unique_ptr<uinput::DeviceCallback> cb =
std::make_unique<uinput::DeviceCallback>(env, callback);
std::unique_ptr<uinput::UinputDevice> d =
- uinput::UinputDevice::open(id, name.c_str(), vid, pid, bus, ffEffectsMax,
+ uinput::UinputDevice::open(id, name.c_str(), vid, pid, bus, ffEffectsMax, port.c_str(),
std::move(cb));
return reinterpret_cast<jlong>(d.release());
}
@@ -303,7 +309,7 @@ static void setAbsInfo(JNIEnv* env, jclass /* clazz */, jint handle, jint axisCo
static JNINativeMethod sMethods[] = {
{"nativeOpenUinputDevice",
- "(Ljava/lang/String;IIIII"
+ "(Ljava/lang/String;IIIIILjava/lang/String;"
"Lcom/android/commands/uinput/Device$DeviceCallback;)J",
reinterpret_cast<void*>(openUinputDevice)},
{"nativeInjectEvent", "(JIII)V", reinterpret_cast<void*>(injectEvent)},
diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.h b/cmds/uinput/jni/com_android_commands_uinput_Device.h
index 5a9a06cfb32e..6da3d7968ed0 100644
--- a/cmds/uinput/jni/com_android_commands_uinput_Device.h
+++ b/cmds/uinput/jni/com_android_commands_uinput_Device.h
@@ -48,6 +48,7 @@ class UinputDevice {
public:
static std::unique_ptr<UinputDevice> open(int32_t id, const char* name, int32_t vid,
int32_t pid, uint16_t bus, uint32_t ff_effects_max,
+ const char* port,
std::unique_ptr<DeviceCallback> callback);
virtual ~UinputDevice();
diff --git a/cmds/uinput/src/com/android/commands/uinput/Device.java b/cmds/uinput/src/com/android/commands/uinput/Device.java
index 62bee7b964bd..732b33d60c15 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Device.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Device.java
@@ -61,7 +61,7 @@ public class Device {
}
private static native long nativeOpenUinputDevice(String name, int id, int vid, int pid,
- int bus, int ffEffectsMax, DeviceCallback callback);
+ int bus, int ffEffectsMax, String port, DeviceCallback callback);
private static native void nativeCloseUinputDevice(long ptr);
private static native void nativeInjectEvent(long ptr, int type, int code, int value);
private static native void nativeConfigure(int handle, int code, int[] configs);
@@ -69,7 +69,7 @@ public class Device {
public Device(int id, String name, int vid, int pid, int bus,
SparseArray<int[]> configuration, int ffEffectsMax,
- SparseArray<InputAbsInfo> absInfo) {
+ SparseArray<InputAbsInfo> absInfo, String port) {
mId = id;
mThread = new HandlerThread("UinputDeviceHandler");
mThread.start();
@@ -88,6 +88,11 @@ public class Device {
} else {
args.arg1 = id + ":" + vid + ":" + pid;
}
+ if (port != null) {
+ args.arg2 = port;
+ } else {
+ args.arg2 = "uinput:" + id + ":" + vid + ":" + pid;
+ }
mHandler.obtainMessage(MSG_OPEN_UINPUT_DEVICE, args).sendToTarget();
mTimeToSend = SystemClock.uptimeMillis();
@@ -142,7 +147,7 @@ public class Device {
case MSG_OPEN_UINPUT_DEVICE:
SomeArgs args = (SomeArgs) msg.obj;
mPtr = nativeOpenUinputDevice((String) args.arg1, args.argi1, args.argi2,
- args.argi3, args.argi4, args.argi5,
+ args.argi3, args.argi4, args.argi5, (String) args.arg2,
new DeviceCallback());
break;
case MSG_INJECT_EVENT:
diff --git a/cmds/uinput/src/com/android/commands/uinput/Event.java b/cmds/uinput/src/com/android/commands/uinput/Event.java
index c4ba05054eda..4b090f5a713c 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Event.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Event.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.stream.IntStream;
import src.com.android.commands.uinput.InputAbsInfo;
@@ -64,6 +65,7 @@ public class Event {
private SparseArray<int[]> mConfiguration;
private int mDuration;
private int mFfEffectsMax = 0;
+ private String mInputport;
private SparseArray<InputAbsInfo> mAbsInfo;
public int getId() {
@@ -110,6 +112,10 @@ public class Event {
return mAbsInfo;
}
+ public String getPort() {
+ return mInputport;
+ }
+
/**
* Convert an event to String.
*/
@@ -124,6 +130,7 @@ public class Event {
+ ", configuration=" + mConfiguration
+ ", duration=" + mDuration
+ ", ff_effects_max=" + mFfEffectsMax
+ + ", port=" + mInputport
+ "}";
}
@@ -178,6 +185,10 @@ public class Event {
mEvent.mAbsInfo = absInfo;
}
+ public void setInputport(String port) {
+ mEvent.mInputport = port;
+ }
+
public Event build() {
if (mEvent.mId == -1) {
throw new IllegalStateException("No event id");
@@ -262,6 +273,9 @@ public class Event {
case "duration":
eb.setDuration(readInt());
break;
+ case "port":
+ eb.setInputport(mReader.nextString());
+ break;
default:
mReader.skipValue();
}
@@ -325,7 +339,7 @@ public class Event {
mReader.beginArray();
while (mReader.hasNext()) {
int type = 0;
- int[] data = null;
+ IntStream data = null;
mReader.beginObject();
while (mReader.hasNext()) {
String name = mReader.nextName();
@@ -334,8 +348,7 @@ public class Event {
type = readInt();
break;
case "data":
- data = readIntList().stream()
- .mapToInt(Integer::intValue).toArray();
+ data = readIntList().stream().mapToInt(Integer::intValue);
break;
default:
consumeRemainingElements();
@@ -346,7 +359,9 @@ public class Event {
}
mReader.endObject();
if (data != null) {
- configuration.put(type, data);
+ final int[] existing = configuration.get(type);
+ configuration.put(type, existing == null ? data.toArray()
+ : IntStream.concat(IntStream.of(existing), data).toArray());
}
}
mReader.endArray();
diff --git a/cmds/uinput/src/com/android/commands/uinput/Uinput.java b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
index f7601a2f7c07..740578e878ac 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Uinput.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
@@ -123,7 +123,7 @@ public class Uinput {
}
int id = e.getId();
Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(),
- e.getConfiguration(), e.getFfEffectsMax(), e.getAbsInfo());
+ e.getConfiguration(), e.getFfEffectsMax(), e.getAbsInfo(), e.getPort());
mDevices.append(id, d);
}