diff options
20 files changed, 283 insertions, 192 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index c605e67853..445df9eeff 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -614,12 +614,6 @@ void IPCThreadState::processPostWriteDerefs() 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 4fd0dc7715..bade9187ac 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -401,7 +401,7 @@ static int open_driver(const char *driver) 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 5d04ebedae..196a41ba55 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -162,12 +162,6 @@ public: // 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 497da2d215..0000000000 --- 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 0c3fbcd2da..5612d1db66 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, FreedBinder) { } } -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 d27d1ecdbe..e117d1189c 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1268,8 +1268,11 @@ int Surface::query(int what, int* value) const { 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 80ff653d1e..371454a3de 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -65,12 +65,12 @@ ComposerService::ComposerService() 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 @@ void ComposerService::connectLocked() { 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 50bd742b6a..fa1071a4e3 100644 --- a/libs/gui/include/private/gui/ComposerService.h +++ b/libs/gui/include/private/gui/ComposerService.h @@ -45,13 +45,12 @@ class ComposerService : public Singleton<ComposerService> 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 ddaa7c7783..d1bbcc55a9 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 9f6ecaa1a0..47c330ffb1 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -725,6 +725,14 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, 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 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, 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 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, 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 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, 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 @@ inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const Fl 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 4265c08a3f..97d3b72347 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.h +++ b/libs/renderengine/skia/SkiaGLRenderEngine.h @@ -90,7 +90,7 @@ private: 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 40f5cf299d..856fff4b01 100644 --- a/libs/renderengine/skia/debug/SkiaCapture.cpp +++ b/libs/renderengine/skia/debug/SkiaCapture.cpp @@ -34,7 +34,7 @@ namespace renderengine { 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 @@ void SkiaCapture::writeToFile() { // 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 @@ void SkiaCapture::writeToFile() { 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 @@ bool SkiaCapture::setupMultiFrameCapture() { 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 5e18e60f93..f1946290ca 100644 --- a/libs/renderengine/skia/debug/SkiaCapture.h +++ b/libs/renderengine/skia/debug/SkiaCapture.h @@ -85,6 +85,8 @@ private: // 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 25c8cefd7d..e99b7ae390 100755 --- a/libs/renderengine/skia/debug/record.sh +++ b/libs/renderengine/skia/debug/record.sh @@ -16,14 +16,22 @@ elif [ "$1" == "rootandsetup" ]; then # 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 @@ sleep $(($1 / 1000 + 4)); # 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 @@ spin() { sleep $1 } -printf "MSKP captured, Waiting for file serialization to finish.\n" - -local_path=~/Downloads/$name +local_path=~/Downloads/ -# wait for the file size to stop changing +get_filename() { + adb shell getprop debug.renderengine.capture_filename +} -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_cmd="adb pull $remote_path $local_path" +echo $adb_pull_cmd +$adb_pull_cmd -adb pull "$remote_path" "$local_path" -if ! [ -f "$local_path" ] ; then - printf "something went wrong with `adb pull`." - exit 4 -fi 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 73a6db5128..560834f5f3 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 @@ VirtualSensor::VirtualSensor() : } // --------------------------------------------------------------------------- + +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 b5375cb9ed..ea181c9877 100644 --- a/services/sensorservice/SensorInterface.h +++ b/services/sensorservice/SensorInterface.h @@ -26,6 +26,7 @@ namespace android { // --------------------------------------------------------------------------- class SensorDevice; class SensorFusion; +class SensorService; class SensorInterface : public VirtualLightRefBase { public: @@ -43,6 +44,9 @@ public: 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 @@ public: 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 @@ protected: 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 617ceefd0e..049ae7c855 100644 --- a/services/sensorservice/SensorList.h +++ b/services/sensorservice/SensorList.h @@ -36,6 +36,15 @@ namespace SensorServiceUtil { 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 @@ public: 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 @@ private: 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 f9491969e2..9df020d1e9 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 @@ Mutex SensorService::sPackageTargetVersionLock; 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 @@ static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSOR 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 @@ void SensorService::onFirstRef() { (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 @@ void SensorService::onFirstRef() { 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 @@ void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) { 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 @@ void SensorService::enableAllSensorsLocked(ConnectionSafeAutolock* connLock) { } 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 @@ status_t SensorService::resetToNormalModeLocked() { 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 @@ void SensorService::cleanupConnection(SensorDirectConnection* c) { 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 a563a60607..def661177c 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -89,9 +89,23 @@ public: 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 @@ public: 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 @@ private: }; 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 @@ private: 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 @@ private: 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 @@ private: 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 2f2cc06c9b..297c0b2f7e 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); } |