Merge "Log supplicant restart count correctly"
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h
index e1b6b57..d3b2062 100644
--- a/include/surfaceflinger/IGraphicBufferAlloc.h
+++ b/include/surfaceflinger/IGraphicBufferAlloc.h
@@ -37,7 +37,7 @@
/* Create a new GraphicBuffer for the client to use.
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) = 0;
+ PixelFormat format, uint32_t usage, status_t* error) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0bd69cf..c8e9c04 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -133,13 +133,13 @@
// Change the scheduling group of a particular thread. The group
// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
// grp is out of range, else another non-zero value with errno set if
-// the operation failed.
+// the operation failed. Thread ID zero means current thread.
extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
// Change the priority AND scheduling group of a particular thread. The priority
// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
// if the priority set failed, else another value if just the group set failed;
-// in either case errno is set.
+// in either case errno is set. Thread ID zero means current thread.
extern int androidSetThreadPriority(pid_t tid, int prio);
#ifdef __cplusplus
@@ -510,6 +510,10 @@
// that case.
status_t requestExitAndWait();
+ // Wait until this object's thread exits. Returns immediately if not yet running.
+ // Do not call from this object's thread; will return WOULD_BLOCK in that case.
+ status_t join();
+
protected:
// exitPending() returns true if requestExit() has been called.
bool exitPending() const;
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 0cd51da..30f8d00 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -43,7 +43,7 @@
}
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) {
+ PixelFormat format, uint32_t usage, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeInt32(w);
@@ -52,14 +52,15 @@
data.writeInt32(usage);
remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
sp<GraphicBuffer> graphicBuffer;
- bool nonNull = (bool)reply.readInt32();
- if (nonNull) {
+ status_t result = reply.readInt32();
+ if (result == NO_ERROR) {
graphicBuffer = new GraphicBuffer();
reply.read(*graphicBuffer);
// reply.readStrongBinder();
// here we don't even have to read the BufferReference from
// the parcel, it'll die with the parcel.
}
+ *error = result;
return graphicBuffer;
}
};
@@ -91,8 +92,10 @@
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t usage = data.readInt32();
- sp<GraphicBuffer> result(createGraphicBuffer(w, h, format, usage));
- reply->writeInt32(result != 0);
+ status_t error;
+ sp<GraphicBuffer> result =
+ createGraphicBuffer(w, h, format, usage, &error);
+ reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
// We add a BufferReference to this parcel to make sure the
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3bf6477..886a3fb 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -352,11 +352,13 @@
((uint32_t(buffer->usage) & usage) != usage))
{
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+ status_t error;
sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage));
+ mGraphicBufferAlloc->createGraphicBuffer(
+ w, h, format, usage, &error));
if (graphicBuffer == 0) {
LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
- return NO_MEMORY;
+ return error;
}
if (updateFormat) {
mPixelFormat = format;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 450cdf1..ce587b3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -31,13 +31,13 @@
ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
mSurfaceControl = mComposerClient->createSurface(
- String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGB_888, 0);
+ String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGBA_8888, 0);
ASSERT_TRUE(mSurfaceControl != NULL);
ASSERT_TRUE(mSurfaceControl->isValid());
SurfaceComposerClient::openGlobalTransaction();
- ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7fffffff));
ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
SurfaceComposerClient::closeGlobalTransaction();
@@ -84,7 +84,7 @@
PixelFormat fmt=0;
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 40000));
+ 0x7fffffff));
ASSERT_TRUE(heap != NULL);
// Set the PROTECTED usage bit and verify that the screenshot fails. Note
@@ -94,6 +94,18 @@
GRALLOC_USAGE_PROTECTED));
ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
ANativeWindowBuffer* buf = 0;
+
+ status_t err = anw->dequeueBuffer(anw.get(), &buf);
+ if (err) {
+ // we could fail if GRALLOC_USAGE_PROTECTED is not supported.
+ // that's okay as long as this is the reason for the failure.
+ // try again without the GRALLOC_USAGE_PROTECTED bit.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ return;
+ }
+ ASSERT_EQ(NO_ERROR, anw->cancelBuffer(anw.get(), buf));
+
for (int i = 0; i < 4; i++) {
// Loop to make sure SurfaceFlinger has retired a protected buffer.
ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
@@ -103,7 +115,7 @@
heap = 0;
w = h = fmt = 0;
ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
- 64, 64, 0, 40000));
+ 64, 64, 0, 0x7fffffff));
ASSERT_TRUE(heap == NULL);
// XXX: This should not be needed, but it seems that the new buffers don't
@@ -126,7 +138,7 @@
heap = 0;
w = h = fmt = 0;
ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 40000));
+ 0x7fffffff));
ASSERT_TRUE(heap != NULL);
}
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 15bb1d2..50312e7 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -316,6 +316,10 @@
#if defined(HAVE_PTHREADS)
pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
if (gDoSchedulingGroup) {
+ // set_sched_policy does not support tid == 0
+ if (tid == 0) {
+ tid = androidGetTid();
+ }
if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
SP_BACKGROUND : SP_FOREGROUND)) {
return PERMISSION_DENIED;
@@ -842,6 +846,25 @@
return mStatus;
}
+status_t Thread::join()
+{
+ Mutex::Autolock _l(mLock);
+ if (mThread == getThreadId()) {
+ LOGW(
+ "Thread (this=%p): don't call join() from this "
+ "Thread object's thread. It's a guaranteed deadlock!",
+ this);
+
+ return WOULD_BLOCK;
+ }
+
+ while (mRunning == true) {
+ mThreadExitedCondition.wait(mLock);
+ }
+
+ return mStatus;
+}
+
bool Thread::exitPending() const
{
Mutex::Autolock _l(mLock);
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index a774841..33125c4 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -103,6 +103,11 @@
{
mNativeWindow = new FramebufferNativeWindow();
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+ if (!fbDev) {
+ LOGE("Display subsystem failed to initialize. check logs. exiting...");
+ exit(0);
+ }
+
mDpiX = mNativeWindow->xdpi;
mDpiY = mNativeWindow->ydpi;
mRefreshRate = fbDev->fps;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 685613e..cccab4a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,9 +163,34 @@
const nsecs_t duration = now - mBootTime;
LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
+
+ // wait patiently for the window manager death
+ const String16 name("window");
+ sp<IBinder> window(defaultServiceManager()->getService(name));
+ if (window != 0) {
+ window->linkToDeath(this);
+ }
+
+ // stop boot animation
property_set("ctl.stop", "bootanim");
}
+void SurfaceFlinger::binderDied(const wp<IBinder>& who)
+{
+ // the window manager died on us. prepare its eulogy.
+
+ // unfreeze the screen in case it was... frozen
+ mFreezeDisplayTime = 0;
+ mFreezeCount = 0;
+ mFreezeDisplay = false;
+
+ // reset screen orientation
+ setOrientation(0, eOrientationDefault, 0);
+
+ // restart the boot-animation
+ property_set("ctl.start", "bootanim");
+}
+
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
@@ -2470,11 +2495,14 @@
GraphicBufferAlloc::~GraphicBufferAlloc() {}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) {
+ PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
status_t err = graphicBuffer->initCheck();
+ *error = err;
if (err != 0 || graphicBuffer->handle == 0) {
- GraphicBuffer::dumpAllocationsToSystemLog();
+ if (err == NO_MEMORY) {
+ GraphicBuffer::dumpAllocationsToSystemLog();
+ }
LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
w, h, strerror(-err), graphicBuffer->handle);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b49fa36..15661f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -96,7 +96,7 @@
GraphicBufferAlloc();
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage);
+ PixelFormat format, uint32_t usage, status_t* error);
};
// ---------------------------------------------------------------------------
@@ -147,6 +147,7 @@
class SurfaceFlinger :
public BinderService<SurfaceFlinger>,
public BnSurfaceComposer,
+ public IBinder::DeathRecipient,
protected Thread
{
public:
@@ -193,6 +194,10 @@
sp<Layer> getLayer(const sp<ISurface>& sur) const;
private:
+ // DeathRecipient interface
+ virtual void binderDied(const wp<IBinder>& who);
+
+private:
friend class Client;
friend class LayerBase;
friend class LayerBaseClient;