Merge "SF: Add defensive check on luma sampling"
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index 5b66b92..ccde12a 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -54,4 +54,9 @@
long getVersionCodeForPackage(in String packageName);
+ /**
+ * Return if each app, identified by its package name allows its audio to be recorded.
+ * Unknown packages are mapped to false.
+ */
+ boolean[] isAudioPlaybackCaptureAllowed(in @utf8InCpp String[] packageNames);
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index f83270d..400daf0 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -833,6 +833,33 @@
}
return reply.readInt32();
}
+
+ virtual status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs) {
+ if (!outAllowedConfigs) return BAD_VALUE;
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getAllowedDisplayConfigs failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(displayToken);
+ if (result != NO_ERROR) {
+ ALOGE("getAllowedDisplayConfigs failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_ALLOWED_DISPLAY_CONFIGS, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getAllowedDisplayConfigs failed to transact: %d", result);
+ return result;
+ }
+ result = reply.readInt32Vector(outAllowedConfigs);
+ if (result != NO_ERROR) {
+ ALOGE("getAllowedDisplayConfigs failed to readInt32Vector: %d", result);
+ return result;
+ }
+ return reply.readInt32();
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1354,6 +1381,15 @@
reply->writeInt32(result);
return result;
}
+ case GET_ALLOWED_DISPLAY_CONFIGS: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> displayToken = data.readStrongBinder();
+ std::vector<int32_t> allowedConfigs;
+ status_t result = getAllowedDisplayConfigs(displayToken, &allowedConfigs);
+ reply->writeInt32Vector(allowedConfigs);
+ reply->writeInt32(result);
+ return result;
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d583e6d..7a39222 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1388,6 +1388,12 @@
allowedConfigs);
}
+status_t SurfaceComposerClient::getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs) {
+ return ComposerService::getComposerService()->getAllowedDisplayConfigs(displayToken,
+ outAllowedConfigs);
+}
+
status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display,
Vector<ColorMode>* outColorModes) {
return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes);
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index eedd5f5..0e576ca 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -368,6 +368,14 @@
*/
virtual status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
const std::vector<int32_t>& allowedConfigs) = 0;
+
+ /*
+ * Returns the allowed display configurations currently set.
+ * The allowedConfigs in a vector of indexes corresponding to the configurations
+ * returned from getDisplayConfigs().
+ */
+ virtual status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs) = 0;
};
// ----------------------------------------------------------------------------
@@ -416,6 +424,7 @@
ADD_REGION_SAMPLING_LISTENER,
REMOVE_REGION_SAMPLING_LISTENER,
SET_ALLOWED_DISPLAY_CONFIGS,
+ GET_ALLOWED_DISPLAY_CONFIGS,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4621a34..e062339 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -117,6 +117,12 @@
static status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
const std::vector<int32_t>& allowedConfigs);
+ // Returns the allowed display configurations currently set.
+ // The allowedConfigs in a vector of indexes corresponding to the configurations
+ // returned from getDisplayConfigs().
+ static status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs);
+
// Gets the list of supported color modes for the given display
static status_t getDisplayColorModes(const sp<IBinder>& display,
Vector<ui::ColorMode>* outColorModes);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 7f1dc84..a7599e0 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -683,6 +683,10 @@
const std::vector<int32_t>& /*allowedConfigs*/) override {
return NO_ERROR;
}
+ status_t getAllowedDisplayConfigs(const sp<IBinder>& /*displayToken*/,
+ std::vector<int32_t>* /*outAllowedConfigs*/) override {
+ return NO_ERROR;
+ }
protected:
IBinder* onAsBinder() override { return nullptr; }
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index d7696f9..a73705b 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -23,6 +23,7 @@
#include <binder/IResultReceiver.h>
#include <binder/Parcel.h>
#include <binder/PermissionCache.h>
+#include <cutils/properties.h>
#include <private/android_filesystem_config.h>
#include <utils/String8.h>
#include <utils/Trace.h>
@@ -38,6 +39,7 @@
namespace {
status_t cmdHelp(int out);
status_t cmdVkjson(int out, int err);
+void dumpGameDriverInfo(std::string* result);
} // namespace
const String16 sDump("android.permission.DUMP");
@@ -96,7 +98,11 @@
}
if (dumpAll) {
+ dumpGameDriverInfo(&result);
+ result.append("\n");
+
mGpuStats->dump(Vector<String16>(), &result);
+ result.append("\n");
}
}
@@ -137,6 +143,18 @@
return NO_ERROR;
}
+void dumpGameDriverInfo(std::string* result) {
+ if (!result) return;
+
+ char stableGameDriver[PROPERTY_VALUE_MAX] = {};
+ property_get("ro.gfx.driver.0", stableGameDriver, "unsupported");
+ StringAppendF(result, "Stable Game Driver: %s\n", stableGameDriver);
+
+ char preReleaseGameDriver[PROPERTY_VALUE_MAX] = {};
+ property_get("ro.gfx.driver.1", preReleaseGameDriver, "unsupported");
+ StringAppendF(result, "Pre-release Game Driver: %s\n", preReleaseGameDriver);
+}
+
} // anonymous namespace
} // namespace android
diff --git a/services/surfaceflinger/AllowedDisplayConfigs.h b/services/surfaceflinger/AllowedDisplayConfigs.h
index e3b9c1f..7ca62ea 100644
--- a/services/surfaceflinger/AllowedDisplayConfigs.h
+++ b/services/surfaceflinger/AllowedDisplayConfigs.h
@@ -54,6 +54,12 @@
return (std::find(mConfigs.begin(), mConfigs.end(), config) != mConfigs.end());
}
+ void getAllowedConfigs(std::vector<int32_t>* outConfigs) const {
+ if (outConfigs) {
+ *outConfigs = mConfigs;
+ }
+ }
+
private:
// add a config to the allowed config set
void addConfig(int32_t config) { mConfigs.push_back(config); }
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 02383a6..2d6d33c 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -49,8 +49,6 @@
Region::const_iterator const tail = region.end();
// Use a lambda do avoid writing the object header when the object is empty
RegionProto* regionProto = getRegionProto();
- uint64_t address = reinterpret_cast<uint64_t>(®ion);
- regionProto->set_id(address);
while (head != tail) {
std::function<RectProto*()> getProtoRect = [&]() { return regionProto->add_rect(); };
writeToProto(*head, getProtoRect);
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index cbc7ada..bd8548c 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -119,8 +119,9 @@
}
} // anonymous namespace
-std::vector<float> sampleBuffer(const sp<GraphicBuffer>& buffer, const Point& leftTop,
- const std::vector<RegionSamplingThread::Descriptor>& descriptors) {
+std::vector<float> RegionSamplingThread::sampleBuffer(
+ const sp<GraphicBuffer>& buffer, const Point& leftTop,
+ const std::vector<RegionSamplingThread::Descriptor>& descriptors) {
void* data_raw = nullptr;
buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, &data_raw);
std::shared_ptr<uint32_t> data(reinterpret_cast<uint32_t*>(data_raw),
@@ -150,7 +151,7 @@
descriptors.emplace_back(descriptor);
}
- Rect sampledArea = sampleRegion.bounds();
+ const Rect sampledArea = sampleRegion.bounds();
sp<const DisplayDevice> device = mFlinger.getDefaultDisplayDevice();
DisplayRenderArea renderArea(device, sampledArea, sampledArea.getWidth(),
@@ -174,8 +175,8 @@
}
// Compute the layer's position on the screen
- Rect bounds = Rect(layer->getBounds());
- ui::Transform transform = layer->getTransform();
+ const Rect bounds = Rect(layer->getBounds());
+ const ui::Transform transform = layer->getTransform();
constexpr bool roundOutwards = true;
Rect transformed = transform.transform(bounds, roundOutwards);
@@ -215,7 +216,7 @@
//
// To avoid this, we drop the mutex while we call into SF.
mMutex.unlock();
- mFlinger.captureScreenCore(renderArea, traverseLayers, buffer, false);
+ mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false);
mMutex.lock();
std::vector<Descriptor> activeDescriptors;
@@ -229,6 +230,8 @@
std::vector<float> lumas = sampleBuffer(buffer, sampledArea.leftTop(), activeDescriptors);
if (lumas.size() != activeDescriptors.size()) {
+ ALOGW("collected %zu median luma values for %zu descriptors", lumas.size(),
+ activeDescriptors.size());
return;
}
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index bf59007..ab06513 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -38,11 +38,16 @@
explicit RegionSamplingThread(SurfaceFlinger& flinger);
~RegionSamplingThread();
+ // Add a listener to receive luma notifications. The luma reported via listener will
+ // report the median luma for the layers under the stopLayerHandle, in the samplingArea region.
void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
const sp<IRegionSamplingListener>& listener);
+ // Remove the listener to stop receiving median luma notifications.
void removeListener(const sp<IRegionSamplingListener>& listener);
+ // Instruct the thread to perform a median luma sampling on the layers.
void sampleNow();
+private:
struct Descriptor {
Rect area = Rect::EMPTY_RECT;
wp<Layer> stopLayer;
@@ -54,8 +59,10 @@
return std::hash<IBinder*>()(p.unsafe_get());
}
};
+ std::vector<float> sampleBuffer(
+ const sp<GraphicBuffer>& buffer, const Point& leftTop,
+ const std::vector<RegionSamplingThread::Descriptor>& descriptors);
-private:
void binderDied(const wp<IBinder>& who) override;
void captureSample() REQUIRES(mMutex);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8ec411f..cd63a0e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4915,6 +4915,7 @@
case GET_HDR_CAPABILITIES:
case SET_ACTIVE_CONFIG:
case SET_ALLOWED_DISPLAY_CONFIGS:
+ case GET_ALLOWED_DISPLAY_CONFIGS:
case SET_ACTIVE_COLOR_MODE:
case INJECT_VSYNC:
case SET_POWER_MODE:
@@ -5498,13 +5499,13 @@
static_cast<android_pixel_format>(reqPixelFormat), 1,
usage, "screenshot");
- return captureScreenCore(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
+ return captureScreenCommon(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
}
-status_t SurfaceFlinger::captureScreenCore(RenderArea& renderArea,
- TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer,
- bool useIdentityTransform) {
+status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
+ TraverseLayersFunction traverseLayers,
+ const sp<GraphicBuffer>& buffer,
+ bool useIdentityTransform) {
// This mutex protects syncFd and captureResult for communication of the return values from the
// main thread back to this Binder thread
std::mutex captureMutex;
@@ -5811,6 +5812,36 @@
return NO_ERROR;
}
+status_t SurfaceFlinger::getAllowedDisplayConfigs(const android::sp<android::IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs) {
+ ATRACE_CALL();
+
+ if (!displayToken) {
+ ALOGE("getAllowedDisplayConfigs: displayToken is null");
+ return BAD_VALUE;
+ }
+
+ if (!outAllowedConfigs) {
+ ALOGE("getAllowedDisplayConfigs: outAllowedConfigs is null");
+ return BAD_VALUE;
+ }
+
+ ConditionalLock stateLock(mStateLock, std::this_thread::get_id() != mMainThreadId);
+ const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+ if (!displayId) {
+ ALOGE("getAllowedDisplayConfigs: display not found");
+ return NAME_NOT_FOUND;
+ }
+
+ std::lock_guard allowedConfigLock(mAllowedConfigsLock);
+ auto allowedConfigIterator = mAllowedConfigs.find(displayId.value());
+ if (allowedConfigIterator != mAllowedConfigs.end()) {
+ allowedConfigIterator->second->getAllowedConfigs(outAllowedConfigs);
+ }
+
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
void SetInputWindowsListener::onSetInputWindowsFinished() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 76d0675..8f80175 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -489,6 +489,8 @@
status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override;
status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
const std::vector<int32_t>& allowedConfigs) override;
+ status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+ std::vector<int32_t>* outAllowedConfigs) override;
/* ------------------------------------------------------------------------
* DeathRecipient interface
@@ -643,8 +645,8 @@
status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
bool useIdentityTransform);
- status_t captureScreenCore(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool useIdentityTransform);
+ status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
+ const sp<GraphicBuffer>& buffer, bool useIdentityTransform);
status_t captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 7ab57f9..7288232 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -132,7 +132,6 @@
LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) {
LayerProtoParser::Region region;
- region.id = regionProto.id();
for (int i = 0; i < regionProto.rect_size(); i++) {
const RectProto& rectProto = regionProto.rect(i);
region.rects.push_back(generateRect(rectProto));
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index a0fb0a0..fd4695e 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -117,7 +117,7 @@
}
message RegionProto {
- uint64 id = 1;
+ reserved 1; // Previously: uint64 id
repeated RectProto rect = 2;
}
diff --git a/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
index 5e82225..ea39bf5 100644
--- a/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
@@ -140,7 +140,7 @@
mExpiredTimerCallback.getInvocable());
// The start hasn't happened, so the callback does not happen.
EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
- EXPECT_FALSE(mResetTimerCallback.waitForCall(1us).has_value());
+ EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
mIdleTimer->stop();
// Final quick check that no more callback were observed.
EXPECT_FALSE(mExpiredTimerCallback.waitForCall(0ms).has_value());
@@ -159,7 +159,7 @@
EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
// Once reset, it should generate another
mIdleTimer->reset();
- EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+ EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
mIdleTimer->stop();
// Final quick check that no more callback were observed.
@@ -171,7 +171,7 @@
mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
mExpiredTimerCallback.getInvocable());
mIdleTimer->start();
- EXPECT_TRUE(mResetTimerCallback.waitForCall(1us).has_value());
+ EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
mIdleTimer->stop();
}
@@ -180,21 +180,21 @@
mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
mExpiredTimerCallback.getInvocable());
mIdleTimer->start();
- EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+ EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
mIdleTimer->stop();
clearPendingCallbacks();
mIdleTimer->reset();
EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
- EXPECT_FALSE(mResetTimerCallback.waitForCall(1ms).has_value());
+ EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
}
TEST_F(IdleTimerTest, noCallbacksAfterStopTest) {
mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
mExpiredTimerCallback.getInvocable());
mIdleTimer->start();
- EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+ EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
mIdleTimer->stop();
clearPendingCallbacks();
@@ -202,7 +202,7 @@
// No more idle events should be observed
EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
- EXPECT_FALSE(mResetTimerCallback.waitForCall(1ms).has_value());
+ EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
}
} // namespace