Merge "Cache a larger variety of clipped rounded rects" into sc-dev
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index c605e67..445df9e 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -614,12 +614,6 @@
mPostWriteStrongDerefs.clear();
}
-void IPCThreadState::createTransactionReference(RefBase* ref)
-{
- ref->incStrong(mProcess.get());
- mPostWriteStrongDerefs.push(ref);
-}
-
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 4fd0dc7..bade918 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -401,7 +401,7 @@
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
if (result == -1) {
- ALOGI("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
+ ALOGD("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
}
} else {
ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 5d04ebe..196a41b 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -162,12 +162,6 @@
// This constant needs to be kept in sync with Binder.UNSET_WORKSOURCE from the Java
// side.
static const int32_t kUnsetWorkSource = -1;
-
- // Create a temp reference until commands in queue flushed to driver
- // Internal only.
- // @internal
- void createTransactionReference(RefBase* ref);
-
private:
IPCThreadState();
~IPCThreadState();
diff --git a/libs/binder/include/binder/ParcelRef.h b/libs/binder/include/binder/ParcelRef.h
deleted file mode 100644
index 497da2d..0000000
--- a/libs/binder/include/binder/ParcelRef.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-
-#include <binder/Parcel.h>
-#include <utils/RefBase.h>
-
-// ---------------------------------------------------------------------------
-namespace android {
-
-/**
- * internal use only
- * @internal
- */
-class ParcelRef : public Parcel, public RefBase
-{
-public:
- static sp<ParcelRef> create() {
- return new ParcelRef();
- }
-
-private:
- ParcelRef() = default;
-};
-
-} // namespace android
-
-// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 0c3fbcd..5612d1d 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -30,7 +30,6 @@
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <binder/ParcelRef.h>
#include <linux/sched.h>
#include <sys/epoll.h>
@@ -891,36 +890,6 @@
}
}
-TEST_F(BinderLibTest, ParcelAllocatedOnAnotherThread) {
- sp<IBinder> server = addServer();
- ASSERT_TRUE(server != nullptr);
-
- Parcel data;
- sp<ParcelRef> reply = ParcelRef::create();
-
- // when we have a Parcel which is deleted on another thread, if it gets
- // deleted, it will tell the kernel this, and it will drop strong references
- // to binder, so that we can't BR_ACQUIRE would fail
- IPCThreadState::self()->createTransactionReference(reply.get());
- ASSERT_EQ(NO_ERROR, server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
- data,
- reply.get()));
-
- // we have sp to binder, but it is not actually acquired by kernel, the
- // transaction is sitting on an out buffer
- sp<IBinder> binder = reply->readStrongBinder();
-
- std::thread([&] {
- // without the transaction reference, this would cause the Parcel to be
- // deallocated before the first thread flushes BR_ACQUIRE
- reply = nullptr;
- IPCThreadState::self()->flushCommands();
- }).join();
-
- ASSERT_NE(nullptr, binder);
- ASSERT_EQ(NO_ERROR, binder->pingBinder());
-}
-
TEST_F(BinderLibTest, CheckNoHeaderMappedInUser) {
Parcel data, reply;
sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index d27d1ec..e117d11 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1268,8 +1268,11 @@
if (err == NO_ERROR) {
return NO_ERROR;
}
- if (composerService()->authenticateSurfaceTexture(
- mGraphicBufferProducer)) {
+ sp<ISurfaceComposer> surfaceComposer = composerService();
+ if (surfaceComposer == nullptr) {
+ return -EPERM; // likely permissions error
+ }
+ if (surfaceComposer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
*value = 1;
} else {
*value = 0;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 80ff653..371454a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -65,12 +65,12 @@
connectLocked();
}
-void ComposerService::connectLocked() {
+bool ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
- while (getService(name, &mComposerService) != NO_ERROR) {
- usleep(250000);
+ mComposerService = waitForService<ISurfaceComposer>(name);
+ if (mComposerService == nullptr) {
+ return false; // fatal error or permission problem
}
- assert(mComposerService != nullptr);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
@@ -86,15 +86,16 @@
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
+ return true;
}
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == nullptr) {
- ComposerService::getInstance().connectLocked();
- assert(instance.mComposerService != nullptr);
- ALOGD("ComposerService reconnected");
+ if (ComposerService::getInstance().connectLocked()) {
+ ALOGD("ComposerService reconnected");
+ }
}
return instance.mComposerService;
}
diff --git a/libs/gui/include/private/gui/ComposerService.h b/libs/gui/include/private/gui/ComposerService.h
index 50bd742..fa1071a 100644
--- a/libs/gui/include/private/gui/ComposerService.h
+++ b/libs/gui/include/private/gui/ComposerService.h
@@ -45,13 +45,12 @@
Mutex mLock;
ComposerService();
- void connectLocked();
+ bool connectLocked();
void composerServiceDied();
friend class Singleton<ComposerService>;
public:
-
// Get a connection to the Composer Service. This will block until
- // a connection is established.
+ // a connection is established. Returns null if permission is denied.
static sp<ISurfaceComposer> getComposerService();
};
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index ddaa7c7..d1bbcc5 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -43,6 +43,11 @@
*/
#define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_SKIA_MS "debug.renderengine.capture_skia_ms"
+/**
+ * Set to the most recently saved file once the capture is finished.
+ */
+#define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME "debug.renderengine.capture_filename"
+
struct ANativeWindowBuffer;
namespace android {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 9f6ecaa..47c330f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -725,6 +725,14 @@
return BAD_VALUE;
}
+ // setup color filter if necessary
+ sk_sp<SkColorFilter> displayColorTransform;
+ if (display.colorTransform != mat4()) {
+ displayColorTransform = SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));
+ }
+ const bool ctModifiesAlpha =
+ displayColorTransform && !displayColorTransform->isAlphaUnchanged();
+
// Find if any layers have requested blur, we'll use that info to decide when to render to an
// offscreen buffer and when to render to the native buffer.
sk_sp<SkSurface> activeSurface(dstSurface);
@@ -734,6 +742,10 @@
if (mBlurFilter) {
bool requiresCompositionLayer = false;
for (const auto& layer : layers) {
+ // if the layer doesn't have blur or it is not visible then continue
+ if (!layerHasBlur(layer, ctModifiesAlpha)) {
+ continue;
+ }
if (layer->backgroundBlurRadius > 0 &&
layer->backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius) {
requiresCompositionLayer = true;
@@ -779,12 +791,6 @@
canvas->drawRegion(clearRegion, paint);
}
- // setup color filter if necessary
- sk_sp<SkColorFilter> displayColorTransform;
- if (display.colorTransform != mat4()) {
- displayColorTransform = SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));
- }
-
for (const auto& layer : layers) {
ATRACE_NAME("DrawLayer");
@@ -850,7 +856,7 @@
const auto [bounds, roundRectClip] =
getBoundsAndClip(layer->geometry.boundaries, layer->geometry.roundedCornersCrop,
layer->geometry.roundedCornersRadius);
- if (mBlurFilter && layerHasBlur(layer)) {
+ if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) {
std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs;
// if multiple layers have blur, then we need to take a snapshot now because
@@ -1188,8 +1194,15 @@
return {SkRRect::MakeRect(bounds), clip};
}
-inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings* layer) {
- return layer->backgroundBlurRadius > 0 || layer->blurRegions.size();
+inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings* layer,
+ bool colorTransformModifiesAlpha) {
+ if (layer->backgroundBlurRadius > 0 || layer->blurRegions.size()) {
+ // return false if the content is opaque and would therefore occlude the blur
+ const bool opaqueContent = !layer->source.buffer.buffer || layer->source.buffer.isOpaque;
+ const bool opaqueAlpha = layer->alpha == 1.0f && !colorTransformModifiesAlpha;
+ return layer->skipContentDraw || !(opaqueContent && opaqueAlpha);
+ }
+ return false;
}
inline SkColor SkiaGLRenderEngine::getSkColor(const vec4& color) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 4265c08..97d3b72 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -90,7 +90,7 @@
inline SkRect getSkRect(const Rect& layer);
inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds,
const FloatRect& crop, float cornerRadius);
- inline bool layerHasBlur(const LayerSettings* layer);
+ inline bool layerHasBlur(const LayerSettings* layer, bool colorTransformModifiesAlpha);
inline SkColor getSkColor(const vec4& color);
inline SkM44 getSkM44(const mat4& matrix);
inline SkPoint3 getSkPoint3(const vec3& vector);
diff --git a/libs/renderengine/skia/debug/SkiaCapture.cpp b/libs/renderengine/skia/debug/SkiaCapture.cpp
index 40f5cf2..856fff4 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.cpp
+++ b/libs/renderengine/skia/debug/SkiaCapture.cpp
@@ -34,7 +34,7 @@
namespace skia {
// The root of the filename to write a recorded SKP to. In order for this file to
-// be written to /data/user/, user must run 'adb shell setenforce 0' in the device.
+// be written to /data/user/, user must run 'adb shell setenforce 0' on the device.
static const std::string CAPTURED_FILENAME_BASE = "/data/user/re_skiacapture";
SkiaCapture::~SkiaCapture() {
@@ -152,11 +152,12 @@
// a smart pointer makes the lambda non-copyable. The lambda is only called
// once, so this is safe.
SkFILEWStream* stream = mOpenMultiPicStream.release();
- CommonPool::post([doc = std::move(mMultiPic), stream] {
+ CommonPool::post([doc = std::move(mMultiPic), stream, name = std::move(mCaptureFile)] {
ALOGD("Finalizing multi frame SKP");
doc->close();
delete stream;
- ALOGD("Multi frame SKP complete.");
+ ALOGD("Multi frame SKP saved to %s.", name.c_str());
+ base::SetProperty(PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME, name);
});
mCaptureRunning = false;
}
@@ -164,12 +165,14 @@
bool SkiaCapture::setupMultiFrameCapture() {
ATRACE_CALL();
ALOGD("Set up multi-frame capture, ms = %llu", mTimerInterval.count());
+ base::SetProperty(PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME, "");
+ const std::scoped_lock lock(mMutex);
- std::string captureFile;
// Attach a timestamp to the file.
- base::StringAppendF(&captureFile, "%s_%lld.mskp", CAPTURED_FILENAME_BASE.c_str(),
+ mCaptureFile.clear();
+ base::StringAppendF(&mCaptureFile, "%s_%lld.mskp", CAPTURED_FILENAME_BASE.c_str(),
std::chrono::steady_clock::now().time_since_epoch().count());
- auto stream = std::make_unique<SkFILEWStream>(captureFile.c_str());
+ auto stream = std::make_unique<SkFILEWStream>(mCaptureFile.c_str());
// We own this stream and need to hold it until close() finishes.
if (stream->isValid()) {
mOpenMultiPicStream = std::move(stream);
@@ -194,7 +197,7 @@
mCaptureRunning = true;
return true;
} else {
- ALOGE("Could not open \"%s\" for writing.", captureFile.c_str());
+ ALOGE("Could not open \"%s\" for writing.", mCaptureFile.c_str());
return false;
}
}
diff --git a/libs/renderengine/skia/debug/SkiaCapture.h b/libs/renderengine/skia/debug/SkiaCapture.h
index 5e18e60..f194629 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.h
+++ b/libs/renderengine/skia/debug/SkiaCapture.h
@@ -85,6 +85,8 @@
// Mutex to ensure that a frame in progress when the timer fires is allowed to run to
// completion before we write the file to disk.
std::mutex mMutex;
+
+ std::string mCaptureFile;
};
} // namespace skia
diff --git a/libs/renderengine/skia/debug/record.sh b/libs/renderengine/skia/debug/record.sh
index 25c8cef..e99b7ae 100755
--- a/libs/renderengine/skia/debug/record.sh
+++ b/libs/renderengine/skia/debug/record.sh
@@ -16,14 +16,22 @@
# first time use requires these changes
adb root
adb shell setenforce 0
- adb shell setprop debug.renderengine.backend "skiagl"
+ adb shell setprop debug.renderengine.backend "skiaglthreaded"
adb shell stop
adb shell start
exit 1;
fi
-# name of the newest file in /data/user/ before starting
-oldname=$(adb shell ls -cr /data/user/ | head -n 1)
+check_permission() {
+ adb shell getenforce
+}
+
+mode=$(check_permission)
+
+if [ "$mode" != "Permissive" ]; then
+ echo "Cannot write to disk from RenderEngine. run 'record.sh rootandsetup'"
+ exit 5
+fi
# record frames for some number of milliseconds.
adb shell setprop debug.renderengine.capture_skia_ms $1
@@ -38,26 +46,6 @@
# the process it is recording.
# /data/user/re_skiacapture_56204430551705.mskp
-# list the files here from newest to oldest, keep only the name of the newest.
-name=$(adb shell ls -cr /data/user/ | head -n 1)
-remote_path=/data/user/$name
-
-if [[ $oldname = $name ]]; then
- echo "No new file written, probably no RenderEngine activity during recording period."
- exit 1
-fi
-
-# return the size of a file in bytes
-adb_filesize() {
- adb shell "wc -c \"$1\"" 2> /dev/null | awk '{print $1}'
-}
-
-mskp_size=$(adb_filesize "/data/user/$name")
-if [[ $mskp_size = "0" ]]; then
- echo "File opened, but remains empty after recording period + wait. Either there was no RenderEngine activity during recording period, or recording process is still working. Check /data/user/$name manually later."
- exit 1
-fi
-
spin() {
case "$spin" in
1) printf '\b|';;
@@ -69,38 +57,28 @@
sleep $1
}
-printf "MSKP captured, Waiting for file serialization to finish.\n"
+local_path=~/Downloads/
-local_path=~/Downloads/$name
+get_filename() {
+ adb shell getprop debug.renderengine.capture_filename
+}
-# wait for the file size to stop changing
-
-timeout=$(( $(date +%s) + 300))
-last_size='0' # output of last size check command
-unstable=true # false once the file size stops changing
-counter=0 # used to perform size check only 1/sec though we update spinner 20/sec
-# loop until the file size is unchanged for 1 second.
-while [ $unstable != 0 ] ; do
+remote_path=""
+counter=0 # used to check only 1/sec though we update spinner 20/sec
+while [ -z $remote_path ] ; do
spin 0.05
counter=$(( $counter+1 ))
if ! (( $counter % 20)) ; then
- new_size=$(adb_filesize "$remote_path")
- unstable=$(($new_size != $last_size))
- last_size=$new_size
- fi
- if [ $(date +%s) -gt $timeout ] ; then
- printf '\bTimed out.\n'
- exit 3
+ remote_path=$(get_filename)
fi
done
printf '\b'
-printf "MSKP file serialized: %s\n" $(echo $last_size | numfmt --to=iec)
+printf "MSKP file serialized to: $remote_path\n"
-adb pull "$remote_path" "$local_path"
-if ! [ -f "$local_path" ] ; then
- printf "something went wrong with `adb pull`."
- exit 4
-fi
+adb_pull_cmd="adb pull $remote_path $local_path"
+echo $adb_pull_cmd
+$adb_pull_cmd
+
adb shell rm "$remote_path"
-printf 'SKP saved to %s\n\n' "$local_path"
\ No newline at end of file
+printf 'SKP saved to %s\n\n' "$local_path"
diff --git a/services/sensorservice/SensorInterface.cpp b/services/sensorservice/SensorInterface.cpp
index 73a6db5..560834f 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -17,6 +17,7 @@
#include "SensorInterface.h"
#include "SensorDevice.h"
#include "SensorFusion.h"
+#include "SensorService.h"
#include <stdint.h>
#include <sys/types.h>
@@ -85,4 +86,35 @@
}
// ---------------------------------------------------------------------------
+
+ProximitySensor::ProximitySensor(const sensor_t& sensor, SensorService& service)
+ : HardwareSensor(sensor), mSensorService(service) {
+}
+
+status_t ProximitySensor::activate(void* ident, bool enabled) {
+ bool wasActive = mActive;
+ status_t status = HardwareSensor::activate(ident, enabled);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ mActive = enabled;
+ if (wasActive != enabled) {
+ mSensorService.onProximityActiveLocked(enabled);
+ }
+ return NO_ERROR;
+}
+
+void ProximitySensor::willDisableAllSensors() {
+ if (mSensorDevice.isSensorActive(mSensor.getHandle())) {
+ mSensorService.onProximityActiveLocked(false);
+ }
+}
+
+void ProximitySensor::didEnableAllSensors() {
+ if (mSensorDevice.isSensorActive(mSensor.getHandle())) {
+ mSensorService.onProximityActiveLocked(true);
+ }
+}
+
+// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index b5375cb..ea181c9 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -26,6 +26,7 @@
// ---------------------------------------------------------------------------
class SensorDevice;
class SensorFusion;
+class SensorService;
class SensorInterface : public VirtualLightRefBase {
public:
@@ -43,6 +44,9 @@
virtual const Sensor& getSensor() const = 0;
virtual bool isVirtual() const = 0;
virtual void autoDisable(void* /*ident*/, int /*handle*/) = 0;
+
+ virtual void willDisableAllSensors() = 0;
+ virtual void didEnableAllSensors() = 0;
};
class BaseSensor : public SensorInterface {
@@ -65,6 +69,9 @@
virtual const Sensor& getSensor() const override { return mSensor; }
virtual void autoDisable(void* /*ident*/, int /*handle*/) override { }
+
+ virtual void willDisableAllSensors() override { }
+ virtual void didEnableAllSensors() override { }
protected:
SensorDevice& mSensorDevice;
Sensor mSensor;
@@ -100,6 +107,20 @@
SensorFusion& mSensorFusion;
};
+// ---------------------------------------------------------------------------
+
+class ProximitySensor : public HardwareSensor {
+public:
+ explicit ProximitySensor(const sensor_t& sensor, SensorService& service);
+
+ status_t activate(void* ident, bool enabled) override;
+
+ void willDisableAllSensors() override;
+ void didEnableAllSensors() override;
+private:
+ SensorService& mSensorService;
+ bool mActive;
+};
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/sensorservice/SensorList.h b/services/sensorservice/SensorList.h
index 617ceef..049ae7c 100644
--- a/services/sensorservice/SensorList.h
+++ b/services/sensorservice/SensorList.h
@@ -36,6 +36,15 @@
class SensorList : public Dumpable {
public:
+ struct Entry {
+ sp<SensorInterface> si;
+ const bool isForDebug;
+ const bool isVirtual;
+ Entry(SensorInterface* si_, bool debug_, bool virtual_) :
+ si(si_), isForDebug(debug_), isVirtual(virtual_) {
+ }
+ };
+
// After SensorInterface * is added into SensorList, it can be assumed that SensorList own the
// object it pointed to and the object should not be released elsewhere.
bool add(int handle, SensorInterface* si, bool isForDebug = false, bool isVirtual = false);
@@ -69,25 +78,6 @@
template <typename TF>
void forEachSensor(const TF& f) const;
- const Sensor& getNonSensor() const { return mNonSensor;}
-
- // Dumpable interface
- virtual std::string dump() const override;
- virtual void dump(util::ProtoOutputStream* proto) const override;
-
- virtual ~SensorList();
-private:
- struct Entry {
- sp<SensorInterface> si;
- const bool isForDebug;
- const bool isVirtual;
- Entry(SensorInterface* si_, bool debug_, bool virtual_) :
- si(si_), isForDebug(debug_), isVirtual(virtual_) {
- }
- };
-
- const static Sensor mNonSensor; //.getName() == "unknown",
-
// Iterate through Entry in sensor list and perform operation f on each Entry.
//
// TF is a function with the signature:
@@ -99,6 +89,16 @@
template <typename TF>
void forEachEntry(const TF& f) const;
+ const Sensor& getNonSensor() const { return mNonSensor;}
+
+ // Dumpable interface
+ virtual std::string dump() const override;
+ virtual void dump(util::ProtoOutputStream* proto) const override;
+
+ virtual ~SensorList();
+private:
+ const static Sensor mNonSensor; //.getName() == "unknown",
+
template <typename T, typename TF>
T getOne(int handle, const TF& accessor, T def = T()) const;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index f949196..9df020d 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -51,7 +51,6 @@
#include "SensorRecord.h"
#include "SensorRegistrationInfo.h"
-#include <ctime>
#include <inttypes.h>
#include <math.h>
#include <sched.h>
@@ -61,8 +60,13 @@
#include <sys/types.h>
#include <unistd.h>
+#include <ctime>
+#include <future>
+
#include <private/android_filesystem_config.h>
+using namespace std::chrono_literals;
+
namespace android {
// ---------------------------------------------------------------------------
@@ -83,6 +87,8 @@
String16 SensorService::sSensorInterfaceDescriptorPrefix =
String16("android.frameworks.sensorservice@");
AppOpsManager SensorService::sAppOpsManager;
+std::atomic_uint64_t SensorService::curProxCallbackSeq(0);
+std::atomic_uint64_t SensorService::completedCallbackSeq(0);
#define SENSOR_SERVICE_DIR "/data/system/sensor_service"
#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key"
@@ -97,7 +103,7 @@
SensorService::SensorService()
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
- mWakeLockAcquired(false) {
+ mWakeLockAcquired(false), mProximityActiveCount(0) {
mUidPolicy = new UidPolicy(this);
mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
}
@@ -168,7 +174,7 @@
(1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
for (ssize_t i=0 ; i<count ; i++) {
- bool useThisSensor=true;
+ bool useThisSensor = true;
switch (list[i].type) {
case SENSOR_TYPE_ACCELEROMETER:
@@ -197,7 +203,11 @@
break;
}
if (useThisSensor) {
- registerSensor( new HardwareSensor(list[i]) );
+ if (list[i].type == SENSOR_TYPE_PROXIMITY) {
+ registerSensor(new ProximitySensor(list[i], *this));
+ } else {
+ registerSensor( new HardwareSensor(list[i]) );
+ }
}
}
@@ -670,6 +680,10 @@
bool hasAccess = hasSensorAccessLocked(conn->getUid(), conn->getOpPackageName());
conn->onSensorAccessChanged(hasAccess);
}
+ mSensors.forEachEntry([](const SensorServiceUtil::SensorList::Entry& e) {
+ e.si->willDisableAllSensors();
+ return true;
+ });
dev.disableAllSensors();
// Clear all pending flush connections for all active sensors. If one of the active
// connections has called flush() and the underlying sensor has been disabled before a
@@ -695,6 +709,10 @@
}
SensorDevice& dev(SensorDevice::getInstance());
dev.enableAllSensors();
+ mSensors.forEachEntry([](const SensorServiceUtil::SensorList::Entry& e) {
+ e.si->didEnableAllSensors();
+ return true;
+ });
for (const sp<SensorDirectConnection>& conn : connLock->getDirectConnections()) {
bool hasAccess = hasSensorAccessLocked(conn->getUid(), conn->getOpPackageName());
conn->onSensorAccessChanged(hasAccess);
@@ -1520,6 +1538,10 @@
if (err == NO_ERROR) {
mCurrentOperatingMode = NORMAL;
dev.enableAllSensors();
+ mSensors.forEachEntry([](const SensorServiceUtil::SensorList::Entry& e) {
+ e.si->didEnableAllSensors();
+ return true;
+ });
}
return err;
}
@@ -1584,6 +1606,80 @@
mConnectionHolder.removeDirectConnection(c);
}
+void SensorService::onProximityActiveLocked(bool isActive) {
+ int prevCount = mProximityActiveCount;
+ bool activeStateChanged = false;
+ if (isActive) {
+ mProximityActiveCount++;
+ activeStateChanged = prevCount == 0;
+ } else {
+ mProximityActiveCount--;
+ if (mProximityActiveCount < 0) {
+ ALOGE("Proximity active count is negative (%d)!", mProximityActiveCount);
+ }
+ activeStateChanged = prevCount > 0 && mProximityActiveCount <= 0;
+ }
+
+ if (activeStateChanged) {
+ notifyProximityStateLocked(mProximityActiveListeners);
+ }
+}
+
+void SensorService::notifyProximityStateLocked(
+ const std::vector<sp<ProximityActiveListener>>& listnrs) {
+ std::async(
+ std::launch::async,
+ [](uint64_t mySeq, bool isActive, std::vector<sp<ProximityActiveListener>> listeners) {
+ while (completedCallbackSeq.load() != mySeq - 1)
+ std::this_thread::sleep_for(1ms);
+ for (auto& listener : listeners)
+ listener->onProximityActive(isActive);
+ completedCallbackSeq++;
+ },
+ ++curProxCallbackSeq, mProximityActiveCount > 0,
+ listnrs /* (this is meant to be a copy) */
+ );
+}
+
+status_t SensorService::addProximityActiveListener(const sp<ProximityActiveListener>& callback) {
+ if (callback == nullptr) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock _l(mLock);
+
+ // Check if the callback was already added.
+ for (const auto& cb : mProximityActiveListeners) {
+ if (cb == callback) {
+ return ALREADY_EXISTS;
+ }
+ }
+
+ mProximityActiveListeners.push_back(callback);
+ std::vector<sp<ProximityActiveListener>> listener(1, callback);
+ notifyProximityStateLocked(listener);
+ return OK;
+}
+
+status_t SensorService::removeProximityActiveListener(
+ const sp<ProximityActiveListener>& callback) {
+ if (callback == nullptr) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock _l(mLock);
+
+ for (auto iter = mProximityActiveListeners.begin();
+ iter != mProximityActiveListeners.end();
+ ++iter) {
+ if (*iter == callback) {
+ mProximityActiveListeners.erase(iter);
+ return OK;
+ }
+ }
+ return NAME_NOT_FOUND;
+}
+
sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
return mSensors.getInterface(handle);
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index a563a60..def6611 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -89,9 +89,23 @@
UID_STATE_IDLE,
};
+ class ProximityActiveListener : public virtual RefBase {
+ public:
+ // Note that the callback is invoked from an async thread and can interact with the
+ // SensorService directly.
+ virtual void onProximityActive(bool isActive) = 0;
+ };
+
+ static char const* getServiceName() ANDROID_API { return "sensorservice"; }
+ SensorService() ANDROID_API;
+
void cleanupConnection(SensorEventConnection* connection);
void cleanupConnection(SensorDirectConnection* c);
+ // Call with mLock held.
+ void onProximityActiveLocked(bool isActive);
+ void notifyProximityStateLocked(const std::vector<sp<ProximityActiveListener>>& listeners);
+
status_t enable(const sp<SensorEventConnection>& connection, int handle,
nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName);
@@ -104,6 +118,9 @@
status_t flushSensor(const sp<SensorEventConnection>& connection,
const String16& opPackageName);
+ status_t addProximityActiveListener(const sp<ProximityActiveListener>& callback) ANDROID_API;
+ status_t removeProximityActiveListener(const sp<ProximityActiveListener>& callback) ANDROID_API;
+
// Returns true if a sensor should be throttled according to our rate-throttling rules.
static bool isSensorInCappedSet(int sensorType);
@@ -305,8 +322,6 @@
};
static const char* WAKE_LOCK_NAME;
- static char const* getServiceName() ANDROID_API { return "sensorservice"; }
- SensorService() ANDROID_API;
virtual ~SensorService();
virtual void onFirstRef();
@@ -326,6 +341,7 @@
virtual int setOperationParameter(
int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
virtual status_t dump(int fd, const Vector<String16>& args);
+
status_t dumpProtoLocked(int fd, ConnectionSafeAutolock* connLock) const;
String8 getSensorName(int handle) const;
String8 getSensorStringType(int handle) const;
@@ -433,6 +449,9 @@
static uint8_t sHmacGlobalKey[128];
static bool sHmacGlobalKeyIsValid;
+ static std::atomic_uint64_t curProxCallbackSeq;
+ static std::atomic_uint64_t completedCallbackSeq;
+
SensorServiceUtil::SensorList mSensors;
status_t mInitCheck;
@@ -476,6 +495,10 @@
std::map<userid_t, sp<SensorPrivacyPolicy>> mMicSensorPrivacyPolicies;
// Checks if the mic sensor privacy is enabled for the uid
bool isMicSensorPrivacyEnabledForUid(uid_t uid);
+
+ // Counts how many proximity sensors are currently active.
+ int mProximityActiveCount;
+ std::vector<sp<ProximityActiveListener>> mProximityActiveListeners;
};
} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 2f2cc06..297c0b2 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -30,10 +30,11 @@
namespace android::compositionengine::impl::planner {
Planner::Planner()
- : mFlattener(base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), false)) {
- // Implicitly, layer caching must also be enabled.
- // E.g., setprop debug.sf.enable_layer_caching 1, or
- // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>]
+ // Implicitly, layer caching must also be enabled for the hole punch or
+ // predictor to have any effect.
+ // E.g., setprop debug.sf.enable_layer_caching 1, or
+ // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>]
+ : mFlattener(base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), true)) {
mPredictorEnabled =
base::GetBoolProperty(std::string("debug.sf.enable_planner_prediction"), false);
}