Merge "Add sysprop for identifying strict-run bugreports" into main
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index c3cf2c2..fc0801c 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -228,10 +228,6 @@
chmod 0666 /sys/kernel/debug/tracing/events/thermal/cdev_update/enable
chmod 0666 /sys/kernel/tracing/events/thermal/cdev_update/enable
-# Tracing disabled by default
- write /sys/kernel/debug/tracing/tracing_on 0
- write /sys/kernel/tracing/tracing_on 0
-
# Read and truncate the kernel trace.
chmod 0666 /sys/kernel/debug/tracing/trace
chmod 0666 /sys/kernel/tracing/trace
@@ -310,11 +306,9 @@
chmod 0666 /sys/kernel/tracing/events/synthetic/suspend_resume_minimal/enable
chmod 0666 /sys/kernel/debug/tracing/events/synthetic/suspend_resume_minimal/enable
-on late-init && property:ro.boot.fastboot.boottrace=enabled
- setprop debug.atrace.tags.enableflags 802922
- setprop persist.traced.enable 0
- write /sys/kernel/debug/tracing/tracing_on 1
- write /sys/kernel/tracing/tracing_on 1
+on late-init && property:ro.boot.fastboot.boottrace=
+ write /sys/kernel/debug/tracing/tracing_on 0
+ write /sys/kernel/tracing/tracing_on 0
# Only create the tracing instance if persist.mm_events.enabled
# Attempting to remove the tracing instance after it has been created
@@ -527,7 +521,6 @@
chmod 0440 /sys/kernel/debug/tracing/hyp/events/hyp/host_mem_abort/id
chmod 0440 /sys/kernel/tracing/hyp/events/hyp/host_mem_abort/id
-
on property:persist.debug.atrace.boottrace=1
start boottrace
@@ -536,10 +529,3 @@
user root
disabled
oneshot
-
-on property:sys.boot_completed=1 && property:ro.boot.fastboot.boottrace=enabled
- setprop debug.atrace.tags.enableflags 0
- setprop persist.traced.enable 1
- write /sys/kernel/debug/tracing/tracing_on 0
- write /sys/kernel/tracing/tracing_on 0
-
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index f520046..9444729 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1418,12 +1418,12 @@
auto ret = sm->list([&](const auto& interfaces) {
for (const std::string& interface : interfaces) {
std::string cleanName = interface;
- std::replace_if(cleanName.begin(),
- cleanName.end(),
- [](char c) {
- return !isalnum(c) &&
- std::string("@-_:.").find(c) == std::string::npos;
- }, '_');
+ std::replace_if(
+ cleanName.begin(), cleanName.end(),
+ [](char c) {
+ return !isalnum(c) && std::string("@-_.").find(c) == std::string::npos;
+ },
+ '_');
const std::string path = ds.bugreport_internal_dir_ + "/lshal_debug_" + cleanName;
bool empty = false;
@@ -1754,6 +1754,20 @@
RunCommand("SYSTEM PROPERTIES", {"getprop"});
+ DumpFile("SYSTEM BUILD-TIME RELEASE FLAGS", "/system/etc/build_flags.json");
+ DumpFile("SYSTEM_EXT BUILD-TIME RELEASE FLAGS", "/system_ext/etc/build_flags.json");
+ DumpFile("PRODUCT BUILD-TIME RELEASE FLAGS", "/product/etc/build_flags.json");
+ DumpFile("VENDOR BUILD-TIME RELEASE FLAGS", "/vendor/etc/build_flags.json");
+
+ DumpFile("SYSTEM BUILD-TIME ACONFIG FLAGS (check dumpstate build_config for runtime values)",
+ "/system/etc/aconfig_flags.textproto");
+ DumpFile("SYSTEM_EXT BUILD-TIME ACONFIG FLAGS (check dumpstate build_config for runtime"
+ " values)", "/system_ext/etc/aconfig_flags.textproto");
+ DumpFile("PRODUCT BUILD-TIME ACONFIG FLAGS (check dumpstate build_config for runtime values)",
+ "/product/etc/aconfig_flags.textproto");
+ DumpFile("VENDOR BUILD-TIME ACONFIG FLAGS (check dumpstate build_config for runtime values)",
+ "/vendor/etc/aconfig_flags.textproto");
+
RunCommand("STORAGED IO INFO", {"storaged", "-u", "-p"});
RunCommand("FILESYSTEMS & FREE SPACE", {"df"});
diff --git a/cmds/installd/CrateManager.cpp b/cmds/installd/CrateManager.cpp
index b17cba1..fd1df35 100644
--- a/cmds/installd/CrateManager.cpp
+++ b/cmds/installd/CrateManager.cpp
@@ -29,9 +29,10 @@
#include <sys/xattr.h>
#include <unistd.h>
-#include <fstream>
-#include <string>
#include <utils.h>
+#include <fstream>
+#include <functional>
+#include <string>
#include "utils.h"
diff --git a/cmds/installd/CrateManager.h b/cmds/installd/CrateManager.h
index 1f30b5d..d9b590f 100644
--- a/cmds/installd/CrateManager.h
+++ b/cmds/installd/CrateManager.h
@@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <functional>
#include <optional>
#include <string>
#include <vector>
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index ecea1d2..c43fdbd 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -18,6 +18,7 @@
#ifndef UTILS_H_
#define UTILS_H_
+#include <functional>
#include <string>
#include <vector>
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index a737bd3..92dc46e 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -173,6 +173,12 @@
}
prebuilt_etc {
+ name: "android.hardware.threadnetwork.prebuilt.xml",
+ src: "android.hardware.threadnetwork.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.hardware.usb.accessory.prebuilt.xml",
src: "android.hardware.usb.accessory.xml",
defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/data/etc/android.hardware.threadnetwork.xml b/data/etc/android.hardware.threadnetwork.xml
new file mode 100644
index 0000000..9cbdc90
--- /dev/null
+++ b/data/etc/android.hardware.threadnetwork.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<!-- Adds the feature indicating support for the ThreadNetwork API -->
+<permissions>
+ <feature name="android.hardware.threadnetwork" />
+</permissions>
diff --git a/libs/binder/rust/binder_tokio/lib.rs b/libs/binder/rust/binder_tokio/lib.rs
index 2d2bf7c..1dc0b24 100644
--- a/libs/binder/rust/binder_tokio/lib.rs
+++ b/libs/binder/rust/binder_tokio/lib.rs
@@ -103,7 +103,12 @@
//
// This shouldn't cause issues with blocking the thread as only one task will run in a
// call to `block_on`, so there aren't other tasks to block.
- let result = spawn_me();
+ //
+ // If the `block_in_place` call fails, then you are driving a current-thread runtime on
+ // the binder threadpool. Instead, it is recommended to use `TokioRuntime<Handle>` when
+ // the runtime is a current-thread runtime, as the current-thread runtime can be driven
+ // only by `Runtime::block_on` calls and not by `Handle::block_on`.
+ let result = tokio::task::block_in_place(spawn_me);
Box::pin(after_spawn(result))
} else {
let handle = tokio::task::spawn_blocking(spawn_me);
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 0bd0781..463c210 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -1023,17 +1023,7 @@
}
if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
- let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
- std::convert::TryFrom::try_from(ibinder.clone());
- if let Ok(service) = service {
- // We were able to associate with our expected class and
- // the service is local.
- todo!()
- //return Ok($crate::Strong::new(Box::new(service)));
- } else {
- // Service is remote
- return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
- }
+ return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
}
Err($crate::StatusCode::BAD_TYPE.into())
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 0b0f9f9..3c615ed 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -723,6 +723,8 @@
parcel.write(&1i32).unwrap();
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
parcel.set_data_position(start).unwrap();
}
@@ -739,6 +741,8 @@
parcel.write(&b"Hello, Binder!\0"[..]).unwrap();
// Skip over string length
+ // SAFETY: str_start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(str_start).is_ok());
}
@@ -747,42 +751,56 @@
assert!(parcel.read::<bool>().unwrap());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<i8>().unwrap(), 72i8);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<u16>().unwrap(), 25928);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<i32>().unwrap(), 1819043144);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<u32>().unwrap(), 1819043144);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<i64>().unwrap(), 4764857262830019912);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<u64>().unwrap(), 4764857262830019912);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -790,6 +808,8 @@
assert_eq!(parcel.read::<f32>().unwrap(), 1143139100000000000000000000.0);
assert_eq!(parcel.read::<f32>().unwrap(), 40.043392);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -797,6 +817,8 @@
assert_eq!(parcel.read::<f64>().unwrap(), 34732488246.197815);
// Skip back to before the string length
+ // SAFETY: str_start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(str_start).is_ok());
}
@@ -810,15 +832,21 @@
let start = parcel.get_data_position();
assert!(parcel.write("Hello, Binder!").is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<Option<String>>().unwrap().unwrap(), "Hello, Binder!",);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(parcel.write("Embedded null \0 inside a string").is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -826,6 +854,8 @@
parcel.read::<Option<String>>().unwrap().unwrap(),
"Embedded null \0 inside a string",
);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -840,6 +870,8 @@
let s3 = "Some more text here.";
assert!(parcel.write(&[s1, s2, s3][..]).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -865,6 +897,8 @@
assert_eq!(parcel.get_data_position(), start + expected_len);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
parcel.set_data_position(start).unwrap();
}
@@ -884,6 +918,8 @@
assert_eq!(4, parcel2.get_data_size());
assert_eq!(Ok(()), parcel2.append_all_from(&parcel1));
assert_eq!(8, parcel2.get_data_size());
+ // SAFETY: 0 is less than the current size of the parcel data buffer, because the parcel is not
+ // empty.
unsafe {
parcel2.set_data_position(0).unwrap();
}
@@ -894,6 +930,8 @@
assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
assert_eq!(Ok(()), parcel2.append_from(&parcel1, 2, 2));
assert_eq!(4, parcel2.get_data_size());
+ // SAFETY: 0 is less than the current size of the parcel data buffer, because the parcel is not
+ // empty.
unsafe {
parcel2.set_data_position(0).unwrap();
}
@@ -902,6 +940,8 @@
let mut parcel2 = Parcel::new();
assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
assert_eq!(2, parcel2.get_data_size());
+ // SAFETY: 0 is less than the current size of the parcel data buffer, because the parcel is not
+ // empty.
unsafe {
parcel2.set_data_position(0).unwrap();
}
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index 038f198..9008a3c 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -1087,6 +1087,8 @@
assert!(custom.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1109,6 +1111,8 @@
assert!(bools.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1118,6 +1122,8 @@
assert_eq!(parcel.read::<u32>().unwrap(), 0);
assert_eq!(parcel.read::<u32>().unwrap(), 0);
assert_eq!(parcel.read::<u32>().unwrap(), 1);
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1133,12 +1139,17 @@
assert!(parcel.write(&u8s[..]).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1148,18 +1159,25 @@
let i8s = [-128i8, 127, 42, -117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(parcel.write(&i8s[..]).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1169,10 +1187,14 @@
let u16s = [u16::max_value(), 12_345, 42, 117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(u16s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1182,6 +1204,9 @@
assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1192,10 +1217,14 @@
let i16s = [i16::max_value(), i16::min_value(), 42, -117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(i16s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1205,6 +1234,9 @@
assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1215,10 +1247,14 @@
let u32s = [u32::max_value(), 12_345, 42, 117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(u32s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1228,6 +1264,9 @@
assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1238,10 +1277,14 @@
let i32s = [i32::max_value(), i32::min_value(), 42, -117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(i32s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1251,6 +1294,9 @@
assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
+
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1261,10 +1307,14 @@
let u64s = [u64::max_value(), 12_345, 42, 117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(u64s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1275,10 +1325,14 @@
let i64s = [i64::max_value(), i64::min_value(), 42, -117];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(i64s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1289,10 +1343,14 @@
let f32s = [std::f32::NAN, std::f32::INFINITY, 1.23456789, std::f32::EPSILON];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(f32s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1305,10 +1363,14 @@
let f64s = [std::f64::NAN, std::f64::INFINITY, 1.234567890123456789, std::f64::EPSILON];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(f64s.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
@@ -1326,10 +1388,14 @@
let strs = [s1, s2, s3, s4];
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
assert!(strs.serialize(&mut parcel.borrowed()).is_ok());
+ // SAFETY: start is less than the current size of the parcel data buffer, because we haven't
+ // made it any shorter since we got the position.
unsafe {
assert!(parcel.set_data_position(start).is_ok());
}
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index ca2cedc..c049b80 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -545,6 +545,11 @@
}
fn get_expected_selinux_context() -> &'static str {
+ // SAFETY: The pointer we pass to `getcon` is valid because it comes from a reference, and
+ // `getcon` doesn't retain it after it returns. If `getcon` succeeds then `out_ptr` will
+ // point to a valid C string, otherwise it will remain null. We check for null, so the
+ // pointer we pass to `CStr::from_ptr` must be a valid pointer to a C string. There is a
+ // memory leak as we don't call `freecon`, but that's fine because this is just a test.
unsafe {
let mut out_ptr = ptr::null_mut();
assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
index 415ede1..37f182e 100644
--- a/libs/binder/rust/tests/ndk_rust_interop.rs
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -28,10 +28,11 @@
///
/// # Safety
///
-/// service_name must be a valid, non-null C-style string (null-terminated).
+/// service_name must be a valid, non-null C-style string (nul-terminated).
#[no_mangle]
pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int {
- let service_name = CStr::from_ptr(service_name).to_str().unwrap();
+ // SAFETY: Our caller promises that service_name is a valid C string.
+ let service_name = unsafe { CStr::from_ptr(service_name) }.to_str().unwrap();
// The Rust class descriptor pointer will not match the NDK one, but the
// descriptor strings match so this needs to still associate.
@@ -85,10 +86,11 @@
///
/// # Safety
///
-/// service_name must be a valid, non-null C-style string (null-terminated).
+/// service_name must be a valid, non-null C-style string (nul-terminated).
#[no_mangle]
pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
- let service_name = CStr::from_ptr(service_name).to_str().unwrap();
+ // SAFETY: Our caller promises that service_name is a valid C string.
+ let service_name = unsafe { CStr::from_ptr(service_name) }.to_str().unwrap();
let service = BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default());
match binder::add_service(service_name, service.as_binder()) {
Ok(_) => StatusCode::OK as c_int,
diff --git a/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
index 29bf92c..ce0f742 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
+++ b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
@@ -105,9 +105,9 @@
for operation in read_operations {
match operation {
ReadOperation::SetDataPosition { pos } => {
+ // Safety: Safe if pos is less than current size of the parcel.
+ // It relies on C++ code for bound checks
unsafe {
- // Safety: Safe if pos is less than current size of the parcel.
- // It relies on C++ code for bound checks
match parcel.set_data_position(pos) {
Ok(result) => result,
Err(e) => println!("error occurred while setting data position: {:?}", e),
diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs
index 6220db4..2b6c282 100644
--- a/libs/binder/rust/tests/serialization.rs
+++ b/libs/binder/rust/tests/serialization.rs
@@ -26,7 +26,7 @@
use binder::binder_impl::{Binder, BorrowedParcel, TransactionCode};
use std::ffi::{c_void, CStr, CString};
-use std::sync::Once;
+use std::sync::OnceLock;
#[allow(
non_camel_case_types,
@@ -70,20 +70,18 @@
};
}
-static SERVICE_ONCE: Once = Once::new();
-static mut SERVICE: Option<SpIBinder> = None;
+static SERVICE: OnceLock<SpIBinder> = OnceLock::new();
/// Start binder service and return a raw AIBinder pointer to it.
///
/// Safe to call multiple times, only creates the service once.
#[no_mangle]
pub extern "C" fn rust_service() -> *mut c_void {
- unsafe {
- SERVICE_ONCE.call_once(|| {
- SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
- });
- SERVICE.as_ref().unwrap().as_raw().cast()
- }
+ let service = SERVICE
+ .get_or_init(|| BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
+ // SAFETY: The SpIBinder will remain alive as long as the program is running because it is in
+ // the static SERVICE, so the pointer is valid forever.
+ unsafe { service.as_raw().cast() }
}
/// Empty interface just to use the declare_binder_interface macro
@@ -113,11 +111,13 @@
bindings::Transaction_TEST_BOOL => {
assert!(parcel.read::<bool>()?);
assert!(!parcel.read::<bool>()?);
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<bool>>()?, unsafe { bindings::TESTDATA_BOOL });
assert_eq!(parcel.read::<Option<Vec<bool>>>()?, None);
reply.write(&true)?;
reply.write(&false)?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_BOOL }[..])?;
reply.write(&(None as Option<Vec<bool>>))?;
}
@@ -125,14 +125,18 @@
assert_eq!(parcel.read::<i8>()?, 0);
assert_eq!(parcel.read::<i8>()?, 1);
assert_eq!(parcel.read::<i8>()?, i8::max_value());
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<i8>>()?, unsafe { bindings::TESTDATA_I8 });
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<u8>>()?, unsafe { bindings::TESTDATA_U8 });
assert_eq!(parcel.read::<Option<Vec<i8>>>()?, None);
reply.write(&0i8)?;
reply.write(&1i8)?;
reply.write(&i8::max_value())?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_I8 }[..])?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_U8 }[..])?;
reply.write(&(None as Option<Vec<i8>>))?;
}
@@ -140,12 +144,14 @@
assert_eq!(parcel.read::<u16>()?, 0);
assert_eq!(parcel.read::<u16>()?, 1);
assert_eq!(parcel.read::<u16>()?, u16::max_value());
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<u16>>()?, unsafe { bindings::TESTDATA_CHARS });
assert_eq!(parcel.read::<Option<Vec<u16>>>()?, None);
reply.write(&0u16)?;
reply.write(&1u16)?;
reply.write(&u16::max_value())?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_CHARS }[..])?;
reply.write(&(None as Option<Vec<u16>>))?;
}
@@ -153,12 +159,14 @@
assert_eq!(parcel.read::<i32>()?, 0);
assert_eq!(parcel.read::<i32>()?, 1);
assert_eq!(parcel.read::<i32>()?, i32::max_value());
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<i32>>()?, unsafe { bindings::TESTDATA_I32 });
assert_eq!(parcel.read::<Option<Vec<i32>>>()?, None);
reply.write(&0i32)?;
reply.write(&1i32)?;
reply.write(&i32::max_value())?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_I32 }[..])?;
reply.write(&(None as Option<Vec<i32>>))?;
}
@@ -166,12 +174,14 @@
assert_eq!(parcel.read::<i64>()?, 0);
assert_eq!(parcel.read::<i64>()?, 1);
assert_eq!(parcel.read::<i64>()?, i64::max_value());
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<i64>>()?, unsafe { bindings::TESTDATA_I64 });
assert_eq!(parcel.read::<Option<Vec<i64>>>()?, None);
reply.write(&0i64)?;
reply.write(&1i64)?;
reply.write(&i64::max_value())?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_I64 }[..])?;
reply.write(&(None as Option<Vec<i64>>))?;
}
@@ -179,12 +189,14 @@
assert_eq!(parcel.read::<u64>()?, 0);
assert_eq!(parcel.read::<u64>()?, 1);
assert_eq!(parcel.read::<u64>()?, u64::max_value());
+ // SAFETY: Just reading an extern constant.
assert_eq!(parcel.read::<Vec<u64>>()?, unsafe { bindings::TESTDATA_U64 });
assert_eq!(parcel.read::<Option<Vec<u64>>>()?, None);
reply.write(&0u64)?;
reply.write(&1u64)?;
reply.write(&u64::max_value())?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_U64 }[..])?;
reply.write(&(None as Option<Vec<u64>>))?;
}
@@ -192,10 +204,12 @@
assert_eq!(parcel.read::<f32>()?, 0f32);
let floats = parcel.read::<Vec<f32>>()?;
assert!(floats[0].is_nan());
+ // SAFETY: Just reading an extern constant.
assert_eq!(floats[1..], unsafe { bindings::TESTDATA_FLOAT }[1..]);
assert_eq!(parcel.read::<Option<Vec<f32>>>()?, None);
reply.write(&0f32)?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_FLOAT }[..])?;
reply.write(&(None as Option<Vec<f32>>))?;
}
@@ -203,10 +217,12 @@
assert_eq!(parcel.read::<f64>()?, 0f64);
let doubles = parcel.read::<Vec<f64>>()?;
assert!(doubles[0].is_nan());
+ // SAFETY: Just reading an extern constant.
assert_eq!(doubles[1..], unsafe { bindings::TESTDATA_DOUBLE }[1..]);
assert_eq!(parcel.read::<Option<Vec<f64>>>()?, None);
reply.write(&0f64)?;
+ // SAFETY: Just reading an extern constant.
reply.write(&unsafe { bindings::TESTDATA_DOUBLE }[..])?;
reply.write(&(None as Option<Vec<f64>>))?;
}
@@ -216,14 +232,17 @@
let s: Option<String> = parcel.read()?;
assert_eq!(s, None);
let s: Option<Vec<Option<String>>> = parcel.read()?;
+ // SAFETY: Just reading an extern constant.
for (s, expected) in s.unwrap().iter().zip(unsafe { bindings::TESTDATA_STRS }.iter()) {
let expected =
+ // SAFETY: Just reading an extern constant.
unsafe { expected.as_ref().and_then(|e| CStr::from_ptr(e).to_str().ok()) };
assert_eq!(s.as_deref(), expected);
}
let s: Option<Vec<Option<String>>> = parcel.read()?;
assert_eq!(s, None);
+ // SAFETY: Just reading an extern constant.
let strings: Vec<Option<String>> = unsafe {
bindings::TESTDATA_STRS
.iter()
@@ -258,8 +277,7 @@
assert!(ibinders[1].is_none());
assert!(parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.is_none());
- let service =
- unsafe { SERVICE.as_ref().expect("Global binder service not initialized").clone() };
+ let service = SERVICE.get().expect("Global binder service not initialized").clone();
reply.write(&service)?;
reply.write(&(None as Option<&SpIBinder>))?;
reply.write(&[Some(&service), None][..])?;
diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp
index bc40864..6712c9c 100644
--- a/libs/binder/tests/binderAllocationLimits.cpp
+++ b/libs/binder/tests/binderAllocationLimits.cpp
@@ -216,16 +216,16 @@
auto server = RpcServer::make();
server->setRootObject(sp<BBinder>::make());
- CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
+ ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
std::thread([server]() { server->join(); }).detach();
- status_t status;
auto session = RpcSession::make();
- status = session->setupUnixDomainClient(addr.c_str());
- CHECK_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
+ status_t status = session->setupUnixDomainClient(addr.c_str());
+ ASSERT_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
auto remoteBinder = session->getRootObject();
+ ASSERT_NE(remoteBinder, nullptr);
size_t mallocs = 0, totalBytes = 0;
{
@@ -233,7 +233,7 @@
mallocs++;
totalBytes += bytes;
});
- CHECK_EQ(OK, remoteBinder->pingBinder());
+ ASSERT_EQ(OK, remoteBinder->pingBinder());
}
EXPECT_EQ(mallocs, 1);
EXPECT_EQ(totalBytes, 40);
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index d352ce5..38c7f7c 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -674,7 +674,7 @@
// session 0 - will check for leaks in destrutor of proc
// session 1 - we want to make sure it gets deleted when we drop all references to it
auto proc = createRpcTestSocketServerProcess(
- {.numThreads = 1, .numIncomingConnectionsBySession = {0, 1}, .numSessions = 2});
+ {.numThreads = 1, .numSessions = 2, .numIncomingConnectionsBySession = {0, 1}});
wp<RpcSession> session = proc.proc->sessions.at(1).session;
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
index 690c39a..96092b1 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
@@ -36,8 +36,8 @@
triage_assignee: "waghpawan@google.com",
// This fuzzer should be used only test fuzzService locally
- fuzz_on_haiku_host: false,
- fuzz_on_haiku_device: false,
+ fuzz_on_haiku_host: true,
+ fuzz_on_haiku_device: true,
},
}
diff --git a/libs/ui/include/ui/FatVector.h b/libs/ui/include/ui/FatVector.h
index cb61e6a..494272b 100644
--- a/libs/ui/include/ui/FatVector.h
+++ b/libs/ui/include/ui/FatVector.h
@@ -65,6 +65,17 @@
free(p);
}
}
+
+ // The STL checks that this member type is present so that
+ // std::allocator_traits<InlineStdAllocator<T, SIZE>>::rebind_alloc<Other>
+ // works. std::vector won't be able to construct an
+ // InlineStdAllocator<Other, SIZE>, because InlineStdAllocator has no
+ // default constructor, but vector presumably doesn't rebind the allocator
+ // because it doesn't allocate internal node types.
+ template <class Other>
+ struct rebind {
+ typedef InlineStdAllocator<Other, SIZE> other;
+ };
Allocation& mAllocation;
};
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index e27b52b..5c00260 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -19,6 +19,7 @@
#include "SensorService.h"
#include <android/util/ProtoOutputStream.h>
+#include <cutils/properties.h>
#include <frameworks/base/core/proto/android/service/sensor_service.proto.h>
namespace android {
@@ -60,10 +61,12 @@
mGyro = uncalibratedGyro;
}
- // 200 Hz for gyro events is a good compromise between precision
- // and power/cpu usage.
- mEstimatedGyroRate = 200;
- mTargetDelayNs = 1000000000LL/mEstimatedGyroRate;
+ // Wearable devices will want to tune this parameter
+ // to 100 (Hz) in device.mk to save some power.
+ int32_t value = property_get_int32(
+ "sensors.aosp_low_power_sensor_fusion.maximum_rate", 200);
+ mEstimatedGyroRate = static_cast<float>(value);
+ mTargetDelayNs = 1000000000LL / mEstimatedGyroRate;
for (int i = 0; i<NUM_FUSION_MODE; ++i) {
mFusions[i].init(i);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8c46515..64348a5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6755,7 +6755,7 @@
if (captureListener) {
// TODO: The future returned by std::async blocks the main thread. Return a chain of
// futures to the Binder thread instead.
- std::async([=]() mutable {
+ (void)std::async([=]() mutable {
ATRACE_NAME("captureListener is nonnull!");
auto fenceResult = renderFuture.get();
// TODO(b/232535621): Change ScreenCaptureResults to store a FenceResult.