Merge "Fail setDisplaySurface if can't enable async" into nyc-mr1-dev
diff --git a/cmds/bugreportz/bugreportz.cpp b/cmds/bugreportz/bugreportz.cpp
index 7bed284..75855cf 100644
--- a/cmds/bugreportz/bugreportz.cpp
+++ b/cmds/bugreportz/bugreportz.cpp
@@ -27,14 +27,17 @@
#include "bugreportz.h"
+static constexpr char BEGIN_PREFIX[] = "BEGIN:";
static constexpr char PROGRESS_PREFIX[] = "PROGRESS:";
static void write_line(const std::string& line, bool show_progress) {
if (line.empty()) return;
- // When not invoked with the -p option, it must skip PROGRESS lines otherwise it
+ // When not invoked with the -p option, it must skip BEGIN and PROGRESS lines otherwise it
// will break adb (which is expecting either OK or FAIL).
- if (!show_progress && android::base::StartsWith(line, PROGRESS_PREFIX)) return;
+ if (!show_progress && (android::base::StartsWith(line, PROGRESS_PREFIX) ||
+ android::base::StartsWith(line, BEGIN_PREFIX)))
+ return;
android::base::WriteStringToFd(line, STDOUT_FILENO);
}
diff --git a/cmds/bugreportz/bugreportz_test.cpp b/cmds/bugreportz/bugreportz_test.cpp
index dfef17f..58b23d1 100644
--- a/cmds/bugreportz/bugreportz_test.cpp
+++ b/cmds/bugreportz/bugreportz_test.cpp
@@ -92,6 +92,7 @@
// Tests 'bugreportz', without any argument - it will ignore progress lines.
TEST_F(BugreportzTest, NoArgument) {
+ WriteToSocket("BEGIN:THE IGNORED PATH WARS HAS!\n"); // Should be ommited.
WriteToSocket("What happens on 'dumpstate',");
WriteToSocket("stays on 'bugreportz'.\n");
WriteToSocket("PROGRESS:Y U NO OMITTED?\n"); // Should be ommited.
@@ -108,6 +109,7 @@
// Tests 'bugreportz -p' - it will just echo dumpstate's output to stdout
TEST_F(BugreportzTest, WithProgress) {
+ WriteToSocket("BEGIN:I AM YOUR PATH\n");
WriteToSocket("What happens on 'dumpstate',");
WriteToSocket("stays on 'bugreportz'.\n");
WriteToSocket("PROGRESS:IS INEVITABLE\n");
@@ -118,6 +120,7 @@
Bugreportz(true);
AssertStdoutEquals(
+ "BEGIN:I AM YOUR PATH\n"
"What happens on 'dumpstate',stays on 'bugreportz'.\n"
"PROGRESS:IS INEVITABLE\n"
"PROGRESS:IS NOT AUTOMATIC\n"
diff --git a/cmds/bugreportz/readme.md b/cmds/bugreportz/readme.md
index 2bc277e..2697f09 100644
--- a/cmds/bugreportz/readme.md
+++ b/cmds/bugreportz/readme.md
@@ -4,10 +4,12 @@
the simple protocol defined below.
# Version 1.1
-On version 1.1, in addition to the `OK` and `FAILURE` lines, `bugreportz -p` generates progress
-lines in the following format:
+On version 1.1, in addition to the `OK` and `FAILURE` lines, when `bugreportz` is invoked with
+`-p`, it outputs the following lines:
-- `PROGRESS:<progress>/<total>`, where `<progress>` is the current progress units out of a max of `<total>`.
+- `BEGIN:<path_to_bugreport_file>` right away.
+- `PROGRESS:<progress>/<total>` as `dumpstate` progresses (where `<progress>` is the current
+progress units out of a max of `<total>`).
## Version 1.0
On version 1.0, `bugreportz` does not generate any output on `stdout` until the bugreport is
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index f74fe39..23629b3 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -689,6 +689,8 @@
run_command("IP6TABLES", 10, "ip6tables", "-L", "-nvx", NULL);
run_command("IPTABLE NAT", 10, "iptables", "-t", "nat", "-L", "-nvx", NULL);
/* no ip6 nat */
+ run_command("IPTABLE MANGLE", 10, "iptables", "-t", "mangle", "-L", "-nvx", NULL);
+ run_command("IP6TABLE MANGLE", 10, "ip6tables", "-t", "mangle", "-L", "-nvx", NULL);
run_command("IPTABLE RAW", 10, "iptables", "-t", "raw", "-L", "-nvx", NULL);
run_command("IP6TABLE RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
}
@@ -1269,15 +1271,22 @@
add_text_zip_entry("version.txt", version);
}
- if (do_update_progress && do_broadcast) {
- std::vector<std::string> am_args = {
- "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
- "--es", "android.intent.extra.NAME", suffix,
- "--ei", "android.intent.extra.ID", std::to_string(id),
- "--ei", "android.intent.extra.PID", std::to_string(getpid()),
- "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL),
- };
- send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
+ if (do_update_progress) {
+ if (do_broadcast) {
+ // clang-format off
+ std::vector<std::string> am_args = {
+ "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
+ "--es", "android.intent.extra.NAME", suffix,
+ "--ei", "android.intent.extra.ID", std::to_string(id),
+ "--ei", "android.intent.extra.PID", std::to_string(getpid()),
+ "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL),
+ };
+ // clang-format on
+ send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
+ }
+ if (use_control_socket) {
+ dprintf(control_socket_fd, "BEGIN:%s\n", path.c_str());
+ }
}
}
@@ -1460,6 +1469,7 @@
if (do_broadcast) {
if (!path.empty()) {
MYLOGI("Final bugreport path: %s\n", path.c_str());
+ // clang-format off
std::vector<std::string> am_args = {
"--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
"--ei", "android.intent.extra.ID", std::to_string(id),
@@ -1468,6 +1478,7 @@
"--es", "android.intent.extra.BUGREPORT", path,
"--es", "android.intent.extra.DUMPSTATE_LOG", log_path
};
+ // clang-format on
if (do_fb) {
am_args.push_back("--es");
am_args.push_back("android.intent.extra.SCREENSHOT");
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index d406179..2014e99 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1568,6 +1568,9 @@
bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
+ // Don't use profile for vm_safe_mode. b/30688277
+ profile_guided = profile_guided && !vm_safe_mode;
+
CHECK(pkgname != nullptr);
CHECK(pkgname[0] != 0);
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 8af4a90..f950276 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -24,6 +24,19 @@
# Maximum number of packages/steps.
MAXIMUM_PACKAGES=1000
+# First ensure the system is booted. This is to work around issues when cmd would
+# infinitely loop trying to get a service manager (which will never come up in that
+# mode). b/30797145
+BOOT_PROPERTY_NAME="dev.bootcomplete"
+
+BOOT_COMPLETE=$(getprop $BOOT_PROPERTY_NAME)
+if [ "$BOOT_COMPLETE" != "1" ] ; then
+ echo "Error: boot-complete not detected."
+ # We must return 0 to not block sideload.
+ exit 0
+fi
+
+
# Compute target slot suffix.
# TODO: Once bootctl is not restricted, we should query from there. Or get this from
# update_engine as a parameter.
diff --git a/cmds/installd/otapreopt_slot.sh b/cmds/installd/otapreopt_slot.sh
index d51ab70..b5786e9 100644
--- a/cmds/installd/otapreopt_slot.sh
+++ b/cmds/installd/otapreopt_slot.sh
@@ -22,10 +22,13 @@
if test -n "$SLOT_SUFFIX" ; then
if test -d /data/ota/$SLOT_SUFFIX/dalvik-cache ; then
log -p i -t otapreopt_slot "Moving A/B artifacts for slot ${SLOT_SUFFIX}."
+ OLD_SIZE=$(du -h -s /data/dalvik-cache)
rm -rf /data/dalvik-cache/*
+ NEW_SIZE=$(du -h -s /data/ota/$SLOT_SUFFIX/dalvik-cache)
mv /data/ota/$SLOT_SUFFIX/dalvik-cache/* /data/dalvik-cache/
rmdir /data/ota/$SLOT_SUFFIX/dalvik-cache
rmdir /data/ota/$SLOT_SUFFIX
+ log -p i -t otapreopt_slot "Moved ${NEW_SIZE} over ${OLD_SIZE}"
else
log -p i -t otapreopt_slot "No A/B artifacts found for slot ${SLOT_SUFFIX}."
fi
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index 73c0367..b214f19 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -18,7 +18,7 @@
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
-LOCAL_SHARED_LIBRARIES := liblog libselinux
+LOCAL_SHARED_LIBRARIES := liblog libcutils libselinux
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_CFLAGS += $(svc_c_flags)
LOCAL_MODULE := servicemanager
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 21fdff0..68e3ceb 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -8,6 +8,8 @@
#include <stdlib.h>
#include <string.h>
+#include <cutils/multiuser.h>
+
#include <private/android_filesystem_config.h>
#include <selinux/android.h>
@@ -121,6 +123,11 @@
static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
{
const char *perm = "add";
+
+ if (multiuser_get_app_id(uid) >= AID_APP) {
+ return 0; /* Don't allow apps to register services */
+ }
+
return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
diff --git a/include/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h
index 69fe51e..62e3877 100644
--- a/include/gui/GraphicBufferAlloc.h
+++ b/include/gui/GraphicBufferAlloc.h
@@ -35,7 +35,7 @@
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t usage,
- status_t* error);
+ std::string requestorName, status_t* error) override;
};
diff --git a/include/gui/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h
index f3c46ec..600cf27 100644
--- a/include/gui/IGraphicBufferAlloc.h
+++ b/include/gui/IGraphicBufferAlloc.h
@@ -21,14 +21,15 @@
#include <sys/types.h>
#include <binder/IInterface.h>
+#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <utils/RefBase.h>
+#include <string>
+
namespace android {
// ----------------------------------------------------------------------------
-class GraphicBuffer;
-
class IGraphicBufferAlloc : public IInterface
{
public:
@@ -37,7 +38,13 @@
/* Create a new GraphicBuffer for the client to use.
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage, status_t* error) = 0;
+ PixelFormat format, uint32_t usage, std::string requestorName,
+ status_t* error) = 0;
+
+ sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t usage, status_t* error) {
+ return createGraphicBuffer(w, h, format, usage, "<Unknown>", error);
+ }
};
// ----------------------------------------------------------------------------
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 3da720f..3e127a1 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -26,6 +26,7 @@
#include <utils/Flattenable.h>
#include <utils/RefBase.h>
+#include <string>
struct ANativeWindowBuffer;
@@ -73,7 +74,7 @@
// creates w * h buffer
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
- uint32_t inUsage);
+ uint32_t inUsage, std::string requestorName = "<Unknown>");
// create a buffer from an existing handle
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
@@ -159,7 +160,7 @@
const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
- uint32_t inUsage);
+ uint32_t inUsage, std::string requestorName);
void free_handle();
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 62ebbd5..28d0238 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -61,7 +61,7 @@
status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
uint32_t usage, buffer_handle_t* handle, uint32_t* stride,
- uint64_t graphicBufferId);
+ uint64_t graphicBufferId, std::string requestorName);
status_t free(buffer_handle_t handle);
@@ -76,6 +76,7 @@
PixelFormat format;
uint32_t usage;
size_t size;
+ std::string requestorName;
};
static Mutex sLock;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index b7b56f0..47ab6f2 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -496,7 +496,8 @@
status_t error;
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
- width, height, format, usage, &error));
+ width, height, format, usage,
+ {mConsumerName.string(), mConsumerName.size()}, &error));
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
@@ -1262,7 +1263,8 @@
for (size_t i = 0; i < newBufferCount; ++i) {
status_t result = NO_ERROR;
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
- allocWidth, allocHeight, allocFormat, allocUsage, &result));
+ allocWidth, allocHeight, allocFormat, allocUsage,
+ {mConsumerName.string(), mConsumerName.size()}, &result));
if (result != NO_ERROR) {
BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
" %u, usage %u)", width, height, format, usage);
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 553b65c..aa0db45 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -345,7 +345,8 @@
// continues to use it.
sp<GraphicBuffer> buffer = new GraphicBuffer(
kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
- GraphicBuffer::USAGE_SW_WRITE_RARELY);
+ GraphicBuffer::USAGE_SW_WRITE_RARELY,
+ "[GLConsumer debug texture]");
uint32_t* bits;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
uint32_t stride = buffer->getStride();
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index 9643402..e6150f4 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -32,9 +32,10 @@
}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
- uint32_t height, PixelFormat format, uint32_t usage, status_t* error) {
- sp<GraphicBuffer> graphicBuffer(
- new GraphicBuffer(width, height, format, usage));
+ uint32_t height, PixelFormat format, uint32_t usage,
+ std::string requestorName, status_t* error) {
+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
+ width, height, format, usage, std::move(requestorName)));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 3009989..7b3b7c1 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -46,13 +46,19 @@
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t usage,
- status_t* error) {
+ std::string requestorName, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeUint32(width);
data.writeUint32(height);
data.writeInt32(static_cast<int32_t>(format));
data.writeUint32(usage);
+ if (requestorName.empty()) {
+ requestorName += "[PID ";
+ requestorName += std::to_string(getpid());
+ requestorName += ']';
+ }
+ data.writeUtf8AsUtf16(requestorName);
remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
sp<GraphicBuffer> graphicBuffer;
status_t result = reply.readInt32();
@@ -101,9 +107,11 @@
uint32_t height = data.readUint32();
PixelFormat format = static_cast<PixelFormat>(data.readInt32());
uint32_t usage = data.readUint32();
- status_t error;
- sp<GraphicBuffer> result =
- createGraphicBuffer(width, height, format, usage, &error);
+ status_t error = NO_ERROR;
+ std::string requestorName;
+ data.readUtf8FromUtf16(&requestorName);
+ sp<GraphicBuffer> result = createGraphicBuffer(width, height,
+ format, usage, requestorName, &error);
reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index f28af6e..97b948d 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -54,7 +54,7 @@
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
- PixelFormat inFormat, uint32_t inUsage)
+ PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
@@ -64,7 +64,8 @@
format =
usage = 0;
handle = NULL;
- mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage);
+ mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage,
+ std::move(requestorName));
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
@@ -151,7 +152,7 @@
allocator.free(handle);
handle = 0;
}
- return initSize(inWidth, inHeight, inFormat, inUsage);
+ return initSize(inWidth, inHeight, inFormat, inUsage, "[Reallocation]");
}
bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
@@ -165,12 +166,12 @@
}
status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
- PixelFormat inFormat, uint32_t inUsage)
+ PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
status_t err = allocator.allocate(inWidth, inHeight, inFormat, inUsage,
- &handle, &outStride, mId);
+ &handle, &outStride, mId, std::move(requestorName));
if (err == NO_ERROR) {
width = static_cast<int>(inWidth);
height = static_cast<int>(inHeight);
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3b83fb6..edfff4d 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -55,13 +55,15 @@
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
if (rec.size) {
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
list.keyAt(i), rec.size/1024.0f,
- rec.width, rec.stride, rec.height, rec.format, rec.usage);
+ rec.width, rec.stride, rec.height, rec.format, rec.usage,
+ rec.requestorName.c_str());
} else {
- snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
list.keyAt(i),
- rec.width, rec.stride, rec.height, rec.format, rec.usage);
+ rec.width, rec.stride, rec.height, rec.format, rec.usage,
+ rec.requestorName.c_str());
}
result.append(buffer);
total += rec.size;
@@ -81,7 +83,7 @@
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage, buffer_handle_t* handle,
- uint32_t* stride, uint64_t graphicBufferId)
+ uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
{
ATRACE_CALL();
@@ -140,6 +142,7 @@
rec.format = format;
rec.usage = usage;
rec.size = static_cast<size_t>(height * (*stride) * bpp);
+ rec.requestorName = std::move(requestorName);
list.add(*handle, rec);
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index eb86860..24e4c19 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -31,7 +31,7 @@
EGL/Loader.cpp \
#
-LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libui
+LOCAL_SHARED_LIBRARIES += libbinder libcutils libutils liblog libui
LOCAL_MODULE:= libEGL
LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
LOCAL_SHARED_LIBRARIES += libdl
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index fcb9357..f41e6e2 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -33,6 +33,8 @@
#include <cutils/properties.h>
#include <cutils/memory.h>
+#include <gui/ISurfaceComposer.h>
+
#include <ui/GraphicBuffer.h>
#include <utils/KeyedVector.h>
@@ -40,6 +42,10 @@
#include <utils/String8.h>
#include <utils/Trace.h>
+#include "binder/Binder.h"
+#include "binder/Parcel.h"
+#include "binder/IServiceManager.h"
+
#include "../egl_impl.h"
#include "../hooks.h"
@@ -1872,18 +1878,77 @@
return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
}
- GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage);
- const status_t err = gBuffer->initCheck();
+#define CHECK_ERROR_CONDITION(message) \
+ if (err != NO_ERROR) { \
+ ALOGE(message); \
+ goto error_condition; \
+ }
+
+ // The holder is used to destroy the buffer if an error occurs.
+ GraphicBuffer* gBuffer = new GraphicBuffer();
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> surfaceFlinger = sm->getService(String16("SurfaceFlinger"));
+ sp<IBinder> allocator;
+ Parcel sc_data, sc_reply, data, reply;
+ status_t err = NO_ERROR;
+ if (sm == NULL) {
+ ALOGE("Unable to connect to ServiceManager");
+ goto error_condition;
+ }
+
+ // Obtain an allocator.
+ if (surfaceFlinger == NULL) {
+ ALOGE("Unable to connect to SurfaceFlinger");
+ goto error_condition;
+ }
+ sc_data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
+ err = surfaceFlinger->transact(
+ BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, sc_data, &sc_reply);
+ CHECK_ERROR_CONDITION("Unable to obtain allocator from SurfaceFlinger");
+ allocator = sc_reply.readStrongBinder();
+
+ if (allocator == NULL) {
+ ALOGE("Unable to obtain an ISurfaceComposer");
+ goto error_condition;
+ }
+ data.writeInterfaceToken(String16("android.ui.IGraphicBufferAlloc"));
+ err = data.writeUint32(width);
+ CHECK_ERROR_CONDITION("Unable to write width");
+ err = data.writeUint32(height);
+ CHECK_ERROR_CONDITION("Unable to write height");
+ err = data.writeInt32(static_cast<int32_t>(format));
+ CHECK_ERROR_CONDITION("Unable to write format");
+ err = data.writeUint32(usage);
+ CHECK_ERROR_CONDITION("Unable to write usage");
+ err = data.writeUtf8AsUtf16(
+ std::string("[eglCreateNativeClientBufferANDROID pid ") +
+ std::to_string(getpid()) + ']');
+ CHECK_ERROR_CONDITION("Unable to write requestor name");
+ err = allocator->transact(IBinder::FIRST_CALL_TRANSACTION, data,
+ &reply);
+ CHECK_ERROR_CONDITION(
+ "Unable to request buffer allocation from surface composer");
+ err = reply.readInt32();
+ CHECK_ERROR_CONDITION("Unable to obtain buffer from surface composer");
+ err = reply.read(*gBuffer);
+ CHECK_ERROR_CONDITION("Unable to read buffer from surface composer");
+
+ err = gBuffer->initCheck();
if (err != NO_ERROR) {
ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
width, height, format, usage, err);
- // Destroy the buffer.
- sp<GraphicBuffer> holder(gBuffer);
- return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
+ goto error_condition;
}
ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
gBuffer, width, height, format, usage);
return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
+
+#undef CHECK_ERROR_CONDITION
+
+error_condition:
+ // Delete the buffer.
+ sp<GraphicBuffer> holder(gBuffer);
+ return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
}
// ----------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 0c4dc26..a24740b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -47,6 +47,7 @@
#include <inttypes.h>
#include <math.h>
+#include <sched.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -71,6 +72,7 @@
#define SENSOR_SERVICE_DIR "/data/system/sensor_service"
#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key"
+#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10
// Permissions.
static const String16 sDump("android.permission.DUMP");
@@ -117,6 +119,15 @@
return true;
}
+// Set main thread to SCHED_FIFO to lower sensor event latency when system is under load
+void SensorService::enableSchedFifoMode() {
+ struct sched_param param = {0};
+ param.sched_priority = SENSOR_SERVICE_SCHED_FIFO_PRIORITY;
+ if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) {
+ ALOGE("Couldn't set SCHED_FIFO for SensorService thread");
+ }
+}
+
void SensorService::onFirstRef() {
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
@@ -261,6 +272,9 @@
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
+
+ // priority can only be changed after run
+ enableSchedFifoMode();
}
}
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 68d4154..1e1ea5a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -215,6 +215,8 @@
// Either read from storage or create a new one.
static bool initializeHmacKey();
+ // Enable SCHED_FIFO priority for thread
+ void enableSchedFifoMode();
static uint8_t sHmacGlobalKey[128];
static bool sHmacGlobalKeyIsValid;
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 415bdca..e14a59b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -43,10 +43,7 @@
{
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
- sp<Layer> layer(mLayers.valueAt(i).promote());
- if (layer != 0) {
- mFlinger->removeLayer(layer);
- }
+ mFlinger->removeLayer(mLayers.valueAt(i));
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2a3c229..785df1a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -559,7 +559,7 @@
#endif
activeCrop.clear();
}
- activeCrop = s.active.transform.inverse().transform(activeCrop);
+ activeCrop = s.active.transform.inverse().transform(activeCrop, true);
// This needs to be here as transform.transform(Rect) computes the
// transformed rect and then takes the bounding box of the result before
// returning. This means
@@ -1331,9 +1331,14 @@
// If this transaction is waiting on the receipt of a frame, generate a sync
// point and send it to the remote layer.
if (mCurrentState.handle != nullptr) {
- sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
- sp<Layer> handleLayer = handle->owner.promote();
- if (handleLayer == nullptr) {
+ sp<IBinder> strongBinder = mCurrentState.handle.promote();
+ sp<Handle> handle = nullptr;
+ sp<Layer> handleLayer = nullptr;
+ if (strongBinder != nullptr) {
+ handle = static_cast<Handle*>(strongBinder.get());
+ handleLayer = handle->owner.promote();
+ }
+ if (strongBinder == nullptr || handleLayer == nullptr) {
ALOGE("[%s] Unable to promote Layer handle", mName.string());
// If we can't promote the layer we are intended to wait on,
// then it is expired or otherwise invalid. Allow this transaction
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c070539..6533953 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -128,7 +128,7 @@
// If set, defers this state update until the Layer identified by handle
// receives a frame with the given frameNumber
- sp<IBinder> handle;
+ wp<IBinder> handle;
uint64_t frameNumber;
// the transparentRegion hint is a bit special, it's latched only
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a36a8cd..2a67f4c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -183,6 +183,10 @@
property_get("debug.sf.disable_backpressure", value, "0");
mPropagateBackpressure = !atoi(value);
ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
+
+ property_get("debug.sf.disable_hwc_vds", value, "0");
+ mUseHwcVirtualDisplays = !atoi(value);
+ ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
}
void SurfaceFlinger::onFirstRef()
@@ -1582,26 +1586,28 @@
// etc.) but no internal state (i.e. a DisplayDevice).
if (state.surface != NULL) {
- int width = 0;
- int status = state.surface->query(
- NATIVE_WINDOW_WIDTH, &width);
- ALOGE_IF(status != NO_ERROR,
- "Unable to query width (%d)", status);
- int height = 0;
- status = state.surface->query(
- NATIVE_WINDOW_HEIGHT, &height);
- ALOGE_IF(status != NO_ERROR,
- "Unable to query height (%d)", status);
- int intFormat = 0;
- status = state.surface->query(
- NATIVE_WINDOW_FORMAT, &intFormat);
- ALOGE_IF(status != NO_ERROR,
- "Unable to query format (%d)", status);
- auto format = static_cast<android_pixel_format_t>(
- intFormat);
+ if (mUseHwcVirtualDisplays) {
+ int width = 0;
+ int status = state.surface->query(
+ NATIVE_WINDOW_WIDTH, &width);
+ ALOGE_IF(status != NO_ERROR,
+ "Unable to query width (%d)", status);
+ int height = 0;
+ status = state.surface->query(
+ NATIVE_WINDOW_HEIGHT, &height);
+ ALOGE_IF(status != NO_ERROR,
+ "Unable to query height (%d)", status);
+ int intFormat = 0;
+ status = state.surface->query(
+ NATIVE_WINDOW_FORMAT, &intFormat);
+ ALOGE_IF(status != NO_ERROR,
+ "Unable to query format (%d)", status);
+ auto format = static_cast<android_pixel_format_t>(
+ intFormat);
- mHwc->allocateVirtualDisplay(width, height, &format,
- &hwcId);
+ mHwc->allocateVirtualDisplay(width, height, &format,
+ &hwcId);
+ }
// TODO: Plumb requested format back up to consumer
@@ -2203,8 +2209,14 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
Mutex::Autolock _l(mStateLock);
+ sp<Layer> layer = weakLayer.promote();
+ if (layer == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2545,14 +2557,7 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------
@@ -2613,6 +2618,7 @@
}
if (currentMode == HWC_POWER_MODE_OFF) {
+ // Turn on the display
getHwComposer().setPowerMode(type, mode);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
@@ -2623,7 +2629,19 @@
mVisibleRegionsDirty = true;
mHasPoweredOff = true;
repaintEverything();
+
+ struct sched_param param = {0};
+ param.sched_priority = 1;
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
+ ALOGW("Couldn't set SCHED_FIFO on display on");
+ }
} else if (mode == HWC_POWER_MODE_OFF) {
+ // Turn off the display
+ struct sched_param param = {0};
+ if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) {
+ ALOGW("Couldn't set SCHED_OTHER on display off");
+ }
+
if (type == DisplayDevice::DISPLAY_PRIMARY) {
disableHardwareVsync(true); // also cancels any in-progress resync
@@ -3264,6 +3282,11 @@
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
+ case 1021: { // Disable HWC virtual displays
+ n = data.readInt32();
+ mUseHwcVirtualDisplays = !n;
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f50f9e7..b98924b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -324,7 +324,7 @@
status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const sp<Layer>& layer);
+ status_t removeLayer(const wp<Layer>& layer);
// add a layer to SurfaceFlinger
status_t addClientLayer(const sp<Client>& client,
@@ -529,6 +529,7 @@
#ifdef USE_HWC2
bool mPropagateBackpressure = true;
#endif
+ bool mUseHwcVirtualDisplays = true;
// these are thread safe
mutable MessageQueue mEventQueue;
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index e7f911e..650d6b4 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -181,6 +181,10 @@
}
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
+
+ property_get("debug.sf.disable_hwc_vds", value, "0");
+ mUseHwcVirtualDisplays = !atoi(value);
+ ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
}
void SurfaceFlinger::onFirstRef()
@@ -1508,9 +1512,10 @@
NATIVE_WINDOW_HEIGHT, &height);
ALOGE_IF(status != NO_ERROR,
"Unable to query height (%d)", status);
- if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
+ if (mUseHwcVirtualDisplays &&
+ (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
(width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
- height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
+ height <= MAX_VIRTUAL_DISPLAY_DIMENSION))) {
hwcDisplayId = allocateHwcDisplayId(state.type);
}
@@ -2120,8 +2125,14 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
Mutex::Autolock _l(mStateLock);
+ sp<Layer> layer = weakLayer.promote();
+ if (layer == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2462,14 +2473,7 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------
@@ -2530,6 +2534,7 @@
}
if (currentMode == HWC_POWER_MODE_OFF) {
+ // Turn on the display
getHwComposer().setPowerMode(type, mode);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
@@ -2540,7 +2545,19 @@
mVisibleRegionsDirty = true;
mHasPoweredOff = true;
repaintEverything();
+
+ struct sched_param param = {0};
+ param.sched_priority = 1;
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
+ ALOGW("Couldn't set SCHED_FIFO on display on");
+ }
} else if (mode == HWC_POWER_MODE_OFF) {
+ // Turn off the display
+ struct sched_param param = {0};
+ if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) {
+ ALOGW("Couldn't set SCHED_OTHER on display off");
+ }
+
if (type == DisplayDevice::DISPLAY_PRIMARY) {
disableHardwareVsync(true); // also cancels any in-progress resync
@@ -3178,6 +3195,11 @@
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
+ case 1021: { // Disable HWC virtual displays
+ n = data.readInt32();
+ mUseHwcVirtualDisplays = !n;
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index c2be91d..6be9ae2 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -196,7 +196,7 @@
return transform( Rect(w, h) );
}
-Rect Transform::transform(const Rect& bounds) const
+Rect Transform::transform(const Rect& bounds, bool roundOutwards) const
{
Rect r;
vec2 lt( bounds.left, bounds.top );
@@ -209,10 +209,17 @@
lb = transform(lb);
rb = transform(rb);
- r.left = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
- r.top = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
- r.right = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
- r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+ if (roundOutwards) {
+ r.left = floorf(min(lt[0], rt[0], lb[0], rb[0]));
+ r.top = floorf(min(lt[1], rt[1], lb[1], rb[1]));
+ r.right = ceilf(max(lt[0], rt[0], lb[0], rb[0]));
+ r.bottom = ceilf(max(lt[1], rt[1], lb[1], rb[1]));
+ } else {
+ r.left = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+ r.top = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+ r.right = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+ r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+ }
return r;
}
diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
index 90855da..66463a0 100644
--- a/services/surfaceflinger/Transform.h
+++ b/services/surfaceflinger/Transform.h
@@ -78,7 +78,8 @@
Rect makeBounds(int w, int h) const;
vec2 transform(int x, int y) const;
Region transform(const Region& reg) const;
- Rect transform(const Rect& bounds) const;
+ Rect transform(const Rect& bounds,
+ bool roundOutwards = false) const;
Transform operator * (const Transform& rhs) const;
// assumes the last row is < 0 , 0 , 1 >
vec2 transform(const vec2& v) const;