diff options
36 files changed, 405 insertions, 163 deletions
diff --git a/data/etc/android.hardware.nfc.ese.xml b/data/etc/android.hardware.nfc.ese.xml new file mode 100644 index 0000000000..6642bb2e1e --- /dev/null +++ b/data/etc/android.hardware.nfc.ese.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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. +--> + +<!-- This feature indicates that the device supports eSE-based NFC card + emulation --> +<permissions> + <feature name="android.hardware.nfc.ese" /> +</permissions> diff --git a/data/etc/android.hardware.nfc.uicc.xml b/data/etc/android.hardware.nfc.uicc.xml new file mode 100644 index 0000000000..4f12de4b56 --- /dev/null +++ b/data/etc/android.hardware.nfc.uicc.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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. +--> + +<!-- This feature indicates that the device supports uicc-based NFC card + emulation --> +<permissions> + <feature name="android.hardware.nfc.uicc" /> +</permissions> diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp index b200314fed..9284acbff3 100644 --- a/libs/android_runtime_lazy/Android.bp +++ b/libs/android_runtime_lazy/Android.bp @@ -33,6 +33,7 @@ cc_library { name: "libandroid_runtime_lazy", vendor_available: true, + double_loadable: true, cflags: [ "-Wall", diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl index ccde12a664..b1c577ecd0 100644 --- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl +++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl @@ -59,4 +59,22 @@ interface IPackageManagerNative { * Unknown packages are mapped to false. */ boolean[] isAudioPlaybackCaptureAllowed(in @utf8InCpp String[] packageNames); + + /* ApplicationInfo.isSystemApp() == true */ + const int LOCATION_SYSTEM = 0x1; + /* ApplicationInfo.isVendor() == true */ + const int LOCATION_VENDOR = 0x2; + /* ApplicationInfo.isProduct() == true */ + const int LOCATION_PRODUCT = 0x4; + /* ApplicationInfo.isProductServices() == true */ + const int LOCATION_PRODUCT_SERVICES = 0x8; + + /** + * Returns a set of bitflags about package location. + * LOCATION_SYSTEM: getApplicationInfo(packageName).isSystemApp() + * LOCATION_VENDOR: getApplicationInfo(packageName).isVendor() + * LOCATION_PRODUCT: getApplicationInfo(packageName).isProduct() + * LOCATION_PRODUCT_SERVICES: getApplicationInfo(packageName).isProductService() + */ + int getLocationFlags(in @utf8InCpp String packageName); } diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp index 0571dccfdc..56521bf2b4 100644 --- a/libs/graphicsenv/Android.bp +++ b/libs/graphicsenv/Android.bp @@ -27,6 +27,7 @@ cc_library_shared { "libbase", "libbinder", "libcutils", + "libdl_android", "liblog", "libutils", ], diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index bc63d315e0..b74d675e4d 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -69,7 +69,8 @@ public: const sp<IBinder>& applyToken, const InputWindowCommands& commands, int64_t desiredPresentTime, - const cached_buffer_t& uncacheBuffer) { + const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -89,6 +90,14 @@ public: data.writeInt64(desiredPresentTime); data.writeStrongBinder(uncacheBuffer.token); data.writeUint64(uncacheBuffer.cacheId); + + if (data.writeVectorSize(listenerCallbacks) == NO_ERROR) { + for (const auto& [listener, callbackIds] : listenerCallbacks) { + data.writeStrongBinder(IInterface::asBinder(listener)); + data.writeInt64Vector(callbackIds); + } + } + remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } @@ -978,8 +987,18 @@ status_t BnSurfaceComposer::onTransact( uncachedBuffer.token = data.readStrongBinder(); uncachedBuffer.cacheId = data.readUint64(); + std::vector<ListenerCallbacks> listenerCallbacks; + int32_t listenersSize = data.readInt32(); + for (int32_t i = 0; i < listenersSize; i++) { + auto listener = + interface_cast<ITransactionCompletedListener>(data.readStrongBinder()); + std::vector<CallbackId> callbackIds; + data.readInt64Vector(&callbackIds); + listenerCallbacks.emplace_back(listener, callbackIds); + } + setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands, - desiredPresentTime, uncachedBuffer); + desiredPresentTime, uncachedBuffer, listenerCallbacks); return NO_ERROR; } case BOOT_FINISHED: { diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index f6ca9e8f0b..3077b21da7 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -86,14 +86,7 @@ status_t layer_state_t::write(Parcel& output) const memcpy(output.writeInplace(16 * sizeof(float)), colorTransform.asArray(), 16 * sizeof(float)); output.writeFloat(cornerRadius); - - if (output.writeVectorSize(listenerCallbacks) == NO_ERROR) { - for (const auto& [listener, callbackIds] : listenerCallbacks) { - output.writeStrongBinder(IInterface::asBinder(listener)); - output.writeInt64Vector(callbackIds); - } - } - + output.writeBool(hasListenerCallbacks); output.writeStrongBinder(cachedBuffer.token); output.writeUint64(cachedBuffer.cacheId); output.writeParcelable(metadata); @@ -163,15 +156,7 @@ status_t layer_state_t::read(const Parcel& input) colorTransform = mat4(static_cast<const float*>(input.readInplace(16 * sizeof(float)))); cornerRadius = input.readFloat(); - - int32_t listenersSize = input.readInt32(); - for (int32_t i = 0; i < listenersSize; i++) { - auto listener = interface_cast<ITransactionCompletedListener>(input.readStrongBinder()); - std::vector<CallbackId> callbackIds; - input.readInt64Vector(&callbackIds); - listenerCallbacks.emplace_back(listener, callbackIds); - } - + hasListenerCallbacks = input.readBool(); cachedBuffer.token = input.readStrongBinder(); cachedBuffer.cacheId = input.readUint64(); input.readParcelable(&metadata); @@ -376,9 +361,9 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eColorTransformChanged; colorTransform = other.colorTransform; } - if (other.what & eListenerCallbacksChanged) { - what |= eListenerCallbacksChanged; - listenerCallbacks = other.listenerCallbacks; + if (other.what & eHasListenerCallbacksChanged) { + what |= eHasListenerCallbacksChanged; + hasListenerCallbacks = other.hasListenerCallbacks; } #ifndef NO_INPUT diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 39cd62fa10..c627898ce2 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -381,7 +381,7 @@ void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle s.state.parentHandleForChild = nullptr; composerStates.add(s); - sf->setTransactionState(composerStates, displayStates, 0, nullptr, {}, -1, {}); + sf->setTransactionState(composerStates, displayStates, 0, nullptr, {}, -1, {}, {}); } void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { @@ -391,7 +391,7 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { uncacheBuffer.token = BufferCache::getInstance().getToken(); uncacheBuffer.cacheId = cacheId; - sf->setTransactionState({}, {}, 0, nullptr, {}, -1, uncacheBuffer); + sf->setTransactionState({}, {}, 0, nullptr, {}, -1, uncacheBuffer, {}); } void SurfaceComposerClient::Transaction::cacheBuffers() { @@ -406,10 +406,16 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { continue; } + // Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste + // time trying to cache them. + if (!s->buffer) { + continue; + } + uint64_t cacheId = 0; status_t ret = BufferCache::getInstance().getCacheId(s->buffer, &cacheId); if (ret == NO_ERROR) { - s->what &= ~static_cast<uint32_t>(layer_state_t::eBufferChanged); + s->what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged); s->buffer = nullptr; } else { cacheId = BufferCache::getInstance().cache(s->buffer); @@ -434,6 +440,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + std::vector<ListenerCallbacks> listenerCallbacks; + // For every listener with registered callbacks for (const auto& [listener, callbackInfo] : mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; @@ -441,11 +449,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { continue; } - // If the listener does not have any SurfaceControls set on this Transaction, send the - // callback now - if (surfaceControls.empty()) { - listener->onTransactionCompleted(ListenerStats::createEmpty(listener, callbackIds)); - } + listenerCallbacks.emplace_back(listener, std::move(callbackIds)); // If the listener has any SurfaceControls set on this Transaction update the surface state for (const auto& surfaceControl : surfaceControls) { @@ -454,8 +458,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { ALOGE("failed to get layer state"); continue; } - s->what |= layer_state_t::eListenerCallbacksChanged; - s->listenerCallbacks.emplace_back(listener, std::move(callbackIds)); + s->what |= layer_state_t::eHasListenerCallbacksChanged; + s->hasListenerCallbacks = true; } } mListenerCallbacks.clear(); @@ -494,7 +498,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, - {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/); + {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/, + listenerCallbacks); mInputWindowCommands.clear(); mStatus = NO_ERROR; return NO_ERROR; diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 0ef5b39641..fe85fdf697 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -20,13 +20,10 @@ #include <stdint.h> #include <sys/types.h> -#include <utils/RefBase.h> -#include <utils/Errors.h> -#include <utils/Timers.h> -#include <utils/Vector.h> - #include <binder/IInterface.h> +#include <gui/ITransactionCompletedListener.h> + #include <ui/ConfigStoreTypes.h> #include <ui/DisplayedFrameStats.h> #include <ui/FrameStats.h> @@ -34,6 +31,11 @@ #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/Timers.h> +#include <utils/Vector.h> + #include <optional> #include <vector> @@ -133,7 +135,8 @@ public: const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - const cached_buffer_t& uncacheBuffer) = 0; + const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks) = 0; /* signal that we're done booting. * Requires ACCESS_SURFACE_FLINGER permission diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 77bf8f1dc5..2256497751 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -23,7 +23,6 @@ #include <utils/Errors.h> #include <gui/IGraphicBufferProducer.h> -#include <gui/ITransactionCompletedListener.h> #include <math/mat4.h> #ifndef NO_INPUT @@ -86,7 +85,7 @@ struct layer_state_t { eApiChanged = 0x04000000, eSidebandStreamChanged = 0x08000000, eColorTransformChanged = 0x10000000, - eListenerCallbacksChanged = 0x20000000, + eHasListenerCallbacksChanged = 0x20000000, eInputInfoChanged = 0x40000000, eCornerRadiusChanged = 0x80000000, eFrameChanged = 0x1'00000000, @@ -120,6 +119,7 @@ struct layer_state_t { surfaceDamageRegion(), api(-1), colorTransform(mat4()), + hasListenerCallbacks(false), bgColorAlpha(0), bgColorDataspace(ui::Dataspace::UNKNOWN), colorSpaceAgnostic(false) { @@ -182,7 +182,7 @@ struct layer_state_t { sp<NativeHandle> sidebandStream; mat4 colorTransform; - std::vector<ListenerCallbacks> listenerCallbacks; + bool hasListenerCallbacks; #ifndef NO_INPUT InputWindowInfo inputInfo; #endif diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 94b669dde4..0ee9bff77f 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -561,7 +561,9 @@ public: const sp<IBinder>& /*applyToken*/, const InputWindowCommands& /*inputWindowCommands*/, int64_t /*desiredPresentTime*/, - const cached_buffer_t& /*cachedBuffer*/) override {} + const cached_buffer_t& /*cachedBuffer*/, + const std::vector<ListenerCallbacks>& /*listenerCallbacks*/) override { + } void bootFinished() override {} bool authenticateSurfaceTexture( diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp index fa928308cf..6d202aec05 100644 --- a/libs/vr/libbufferhub/Android.bp +++ b/libs/vr/libbufferhub/Android.bp @@ -59,9 +59,6 @@ cc_library { "libbufferhub_headers", "libnativebase_headers", ], - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } cc_test { @@ -70,7 +67,4 @@ cc_test { shared_libs: sharedLibraries, header_libs: headerLibraries, name: "buffer_hub-test", - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp index 20894e3588..9f72c05f0c 100644 --- a/libs/vr/libbufferhubqueue/Android.bp +++ b/libs/vr/libbufferhubqueue/Android.bp @@ -59,9 +59,6 @@ cc_library_shared { static_libs: staticLibraries, shared_libs: sharedLibraries, header_libs: headerLibraries, - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } subdirs = ["benchmarks", "tests"] diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp index 357dffe193..3260447390 100644 --- a/libs/vr/libdvr/tests/Android.bp +++ b/libs/vr/libdvr/tests/Android.bp @@ -49,9 +49,6 @@ cc_test { "-g", ], name: "dvr_api-test", - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } cc_test { diff --git a/libs/vr/libvrflinger/tests/Android.bp b/libs/vr/libvrflinger/tests/Android.bp index c884cb3cfe..410e2344ce 100644 --- a/libs/vr/libvrflinger/tests/Android.bp +++ b/libs/vr/libvrflinger/tests/Android.bp @@ -33,7 +33,4 @@ cc_test { "-Werror", ], name: "vrflinger_test", - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index ac1d492adf..52c68df814 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -47,7 +47,7 @@ cc_defaults { "libhwbinder", "liblayers_proto", "liblog", - "libnativewindow", + "libnativewindow", "libpdx_default_transport", "libprocessgroup", "libprotobuf-cpp-lite", @@ -56,7 +56,7 @@ cc_defaults { "libui", "libinput", "libutils", - "libSurfaceFlingerProperties", + "libSurfaceFlingerProp", ], static_libs: [ "libcompositionengine", @@ -138,8 +138,9 @@ filegroup { "LayerVector.cpp", "MonitoredProducer.cpp", "NativeWindowSurface.cpp", - "RenderArea.cpp", + "RefreshRateOverlay.cpp", "RegionSamplingThread.cpp", + "RenderArea.cpp", "Scheduler/DispSync.cpp", "Scheduler/DispSyncSource.cpp", "Scheduler/EventControlThread.cpp", @@ -221,7 +222,7 @@ cc_binary { srcs: [":surfaceflinger_binary_sources"], shared_libs: [ "libsurfaceflinger", - "libSurfaceFlingerProperties", + "libSurfaceFlingerProp", ], } @@ -232,10 +233,9 @@ subdirs = [ ] cc_library_shared { - name: "libSurfaceFlingerProperties", + name: "libSurfaceFlingerProp", srcs: [ "SurfaceFlingerProperties.cpp", - "sysprop/*.sysprop", ], shared_libs: [ "android.hardware.configstore-utils", @@ -247,6 +247,10 @@ cc_library_shared { "libhwbinder", "libui", "libutils", + "liblog", + ], + static_libs: [ + "SurfaceFlingerProperties", ], export_shared_lib_headers: [ "android.hardware.graphics.common@1.2", @@ -254,4 +258,7 @@ cc_library_shared { "libhidltransport", "libhwbinder", ], + export_static_lib_headers: [ + "SurfaceFlingerProperties", + ], } diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp new file mode 100644 index 0000000000..e70bfe4b1e --- /dev/null +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2019 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. + */ + +#include "RefreshRateOverlay.h" +#include "Client.h" +#include "Layer.h" + +namespace android { + +using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; + +RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger) + : mFlinger(flinger), mClient(new Client(&mFlinger)) { + createLayer(); +} + +bool RefreshRateOverlay::createLayer() { + const status_t ret = + mFlinger.createLayer(String8("RefreshRateOverlay"), mClient, 0, 0, + PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor, + LayerMetadata(), &mIBinder, &mGbp, &mLayer); + if (ret) { + ALOGE("failed to color layer"); + return false; + } + + mLayer = mClient->getLayerUser(mIBinder); + mLayer->setCrop_legacy(Rect(0, 0, 200, 100), true); + mLayer->setLayer(INT32_MAX - 2); + + return true; +} + +void RefreshRateOverlay::changeRefreshRate(RefreshRateType type) { + const half3& color = (type == RefreshRateType::PERFORMANCE) ? GREEN : RED; + mLayer->setColor(color); + mFlinger.setTransactionFlags(eTransactionMask); +} + +}; // namespace android diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h new file mode 100644 index 0000000000..ce29bc3243 --- /dev/null +++ b/services/surfaceflinger/RefreshRateOverlay.h @@ -0,0 +1,43 @@ +/* + * Copyright 2019 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 "SurfaceFlinger.h" + +namespace android { + +using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; + +class RefreshRateOverlay { +public: + RefreshRateOverlay(SurfaceFlinger& flinger); + + void changeRefreshRate(RefreshRateType type); + +private: + bool createLayer(); + + SurfaceFlinger& mFlinger; + sp<Client> mClient; + sp<Layer> mLayer; + sp<IBinder> mIBinder; + sp<IGraphicBufferProducer> mGbp; + + const half3 RED = half3(1.0f, 0.0f, 0.0f); + const half3 GREEN = half3(0.0f, 1.0f, 0.0f); +}; + +}; // namespace android diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 78bf7c5c49..a760079069 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -97,7 +97,7 @@ DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t times return event; } -DisplayEventReceiver::Event makeConfigChanged(uint32_t displayId, int32_t configId) { +DisplayEventReceiver::Event makeConfigChanged(PhysicalDisplayId displayId, int32_t configId) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED, displayId, systemTime()}; event.config.configId = configId; diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index 9e95f95092..1aa6aded75 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -57,7 +57,7 @@ public: } ~RefreshRateConfigs() = default; - const std::unordered_map<RefreshRateType, std::shared_ptr<RefreshRate>>& getRefreshRates() { + const std::map<RefreshRateType, std::shared_ptr<RefreshRate>>& getRefreshRates() { return mRefreshRates; } std::shared_ptr<RefreshRate> getRefreshRate(RefreshRateType type) { @@ -120,7 +120,7 @@ private: } } - std::unordered_map<RefreshRateType, std::shared_ptr<RefreshRate>> mRefreshRates; + std::map<RefreshRateType, std::shared_ptr<RefreshRate>> mRefreshRates; }; } // namespace scheduler diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 916e531461..c0d7f2d726 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -84,6 +84,7 @@ #include "LayerVector.h" #include "MonitoredProducer.h" #include "NativeWindowSurface.h" +#include "RefreshRateOverlay.h" #include "StartPropertySetThread.h" #include "SurfaceFlinger.h" #include "SurfaceInterceptor.h" @@ -128,8 +129,6 @@ using ui::DisplayPrimaries; using ui::Hdr; using ui::RenderIntent; -using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; - namespace { #pragma clang diagnostic push @@ -281,6 +280,7 @@ SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory, mFactory(factory), mTransactionPending(false), mAnimTransactionPending(false), + mTraversalNeededMainThread(false), mLayersRemoved(false), mLayersAdded(false), mBootTime(systemTime()), @@ -942,24 +942,18 @@ int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) { return display->getActiveConfig(); } -void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, - Scheduler::ConfigEvent event) { +void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) { ATRACE_CALL(); // Lock is acquired by setRefreshRateTo. - const auto display = getDisplayDeviceLocked(displayToken); + const auto display = getDisplayDeviceLocked(info.displayToken); if (!display) { - ALOGE("Attempt to set active config %d for invalid display token %p", mode, - displayToken.get()); + ALOGE("Attempt to set active config %d for invalid display token %p", info.configId, + info.displayToken.get()); return; } if (display->isVirtual()) { - ALOGW("Attempt to set active config %d for virtual display", mode); - return; - } - int currentDisplayPowerMode = display->getPowerMode(); - if (currentDisplayPowerMode != HWC_POWER_MODE_NORMAL) { - // Don't change active config when in AoD. + ALOGW("Attempt to set active config %d for virtual display", info.configId); return; } @@ -967,8 +961,9 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int // config twice. However event generation config might have changed so we need to update it // accordingly std::lock_guard<std::mutex> lock(mActiveConfigLock); - const Scheduler::ConfigEvent desiredConfig = mDesiredActiveConfig.event | event; - mDesiredActiveConfig = ActiveConfigInfo{mode, displayToken, desiredConfig}; + const Scheduler::ConfigEvent prevConfig = mDesiredActiveConfig.event; + mDesiredActiveConfig = info; + mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig; if (!mDesiredActiveConfigChanged) { // This is the first time we set the desired @@ -979,6 +974,10 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int } mDesiredActiveConfigChanged = true; ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged); + + if (mRefreshRateOverlay) { + mRefreshRateOverlay->changeRefreshRate(mDesiredActiveConfig.type); + } } status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mode) { @@ -1041,6 +1040,7 @@ bool SurfaceFlinger::performSetActiveConfig() NO_THREAD_SAFETY_ANALYSIS { // on both cases there is nothing left to do std::lock_guard<std::mutex> lock(mActiveConfigLock); mScheduler->pauseVsyncCallback(mAppConnectionHandle, false); + mDesiredActiveConfig.event = Scheduler::ConfigEvent::None; mDesiredActiveConfigChanged = false; ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged); return false; @@ -1491,7 +1491,7 @@ void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, Scheduler::Co } mPhaseOffsets->setRefreshRateType(refreshRate); - setDesiredActiveConfig(getInternalDisplayTokenLocked(), desiredConfigId, event); + setDesiredActiveConfig({refreshRate, desiredConfigId, getInternalDisplayTokenLocked(), event}); } void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId, @@ -2778,7 +2778,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) * (perform the transaction for each of them if needed) */ - if (transactionFlags & eTraversalNeeded) { + if ((transactionFlags & eTraversalNeeded) || mTraversalNeededMainThread) { mCurrentState.traverseInZOrder([&](Layer* layer) { uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) return; @@ -2791,6 +2791,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) mInputInfoChanged = true; } }); + mTraversalNeededMainThread = false; } /* @@ -3523,14 +3524,14 @@ bool SurfaceFlinger::flushTransactionQueues() { while (!transactionQueue.empty()) { const auto& - [states, displays, flags, desiredPresentTime, uncacheBuffer, postTime, - privileged] = transactionQueue.front(); + [states, displays, flags, desiredPresentTime, uncacheBuffer, listenerCallbacks, + postTime, privileged] = transactionQueue.front(); if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) { break; } applyTransactionState(states, displays, flags, mPendingInputWindowCommands, - desiredPresentTime, uncacheBuffer, postTime, privileged, - /*isMainThread*/ true); + desiredPresentTime, uncacheBuffer, listenerCallbacks, postTime, + privileged, /*isMainThread*/ true); transactionQueue.pop(); } @@ -3588,7 +3589,8 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - const cached_buffer_t& uncacheBuffer) { + const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks) { ATRACE_CALL(); const int64_t postTime = systemTime(); @@ -3605,13 +3607,14 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states, if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() || !transactionIsReadyToBeApplied(desiredPresentTime, states)) { mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime, - uncacheBuffer, postTime, privileged); + uncacheBuffer, listenerCallbacks, postTime, + privileged); setTransactionFlags(eTransactionNeeded); return; } applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime, - uncacheBuffer, postTime, privileged); + uncacheBuffer, listenerCallbacks, postTime, privileged); } void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, @@ -3619,6 +3622,7 @@ void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks, const int64_t postTime, bool privileged, bool isMainThread) { uint32_t transactionFlags = 0; @@ -3645,7 +3649,15 @@ void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, uint32_t clientStateFlags = 0; for (const ComposerState& state : states) { - clientStateFlags |= setClientStateLocked(state, desiredPresentTime, postTime, privileged); + clientStateFlags |= setClientStateLocked(state, desiredPresentTime, listenerCallbacks, + postTime, privileged); + } + + // In case the client has sent a Transaction that should receive callbacks but without any + // SurfaceControls that should be included in the callback, send the listener and callbackIds + // to the callback thread so it can send an empty callback + for (const auto& [listener, callbackIds] : listenerCallbacks) { + mTransactionCompletedThread.addCallback(listener, callbackIds); } // If the state doesn't require a traversal and there are callbacks, send them now if (!(clientStateFlags & eTraversalNeeded)) { @@ -3668,6 +3680,13 @@ void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, transactionFlags = eTransactionNeeded; } + // If we are on the main thread, we are about to preform a traversal. Clear the traversal bit + // so we don't have to wake up again next frame to preform an uneeded traversal. + if (isMainThread && (transactionFlags & eTraversalNeeded)) { + transactionFlags = transactionFlags & (~eTraversalNeeded); + mTraversalNeededMainThread = true; + } + if (transactionFlags) { if (mInterceptor->isEnabled()) { mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags); @@ -3766,9 +3785,10 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess() { return true; } -uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState, - int64_t desiredPresentTime, int64_t postTime, - bool privileged) { +uint32_t SurfaceFlinger::setClientStateLocked( + const ComposerState& composerState, int64_t desiredPresentTime, + const std::vector<ListenerCallbacks>& listenerCallbacks, int64_t postTime, + bool privileged) { const layer_state_t& s = composerState.state; sp<Client> client(static_cast<Client*>(composerState.client.get())); @@ -3994,9 +4014,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState } } std::vector<sp<CallbackHandle>> callbackHandles; - if ((what & layer_state_t::eListenerCallbacksChanged) && (!s.listenerCallbacks.empty())) { + if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!listenerCallbacks.empty())) { mTransactionCompletedThread.run(); - for (const auto& [listener, callbackIds] : s.listenerCallbacks) { + for (const auto& [listener, callbackIds] : listenerCallbacks) { callbackHandles.emplace_back(new CallbackHandle(listener, callbackIds, s.surface)); } } @@ -4257,7 +4277,7 @@ void SurfaceFlinger::onInitializeDisplays() { d.width = 0; d.height = 0; displays.add(d); - setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}); + setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}, {}); setPowerModeInternal(display, HWC_POWER_MODE_NORMAL); @@ -5021,9 +5041,9 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { code == IBinder::SYSPROPS_TRANSACTION) { return OK; } - // Numbers from 1000 to 1033 are currently used for backdoors. The code + // Numbers from 1000 to 1034 are currently used for backdoors. The code // in onTransact verifies that the user is root, and has access to use SF. - if (code >= 1000 && code <= 1033) { + if (code >= 1000 && code <= 1034) { ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code); return OK; } @@ -5339,6 +5359,18 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r reply->writeInt32(NO_ERROR); return NO_ERROR; } + case 1034: { + // TODO(b/129297325): expose this via developer menu option + n = data.readInt32(); + if (n && !mRefreshRateOverlay) { + std::lock_guard<std::mutex> lock(mActiveConfigLock); + mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this); + mRefreshRateOverlay->changeRefreshRate(mDesiredActiveConfig.type); + } else if (!n) { + mRefreshRateOverlay.reset(); + } + return NO_ERROR; + } } } return err; @@ -5806,30 +5838,14 @@ void SurfaceFlinger::setAllowedDisplayConfigsInternal( mAllowedConfigs[*displayId] = std::move(allowedConfigs); } - // make sure that the current config is still allowed - int currentConfigIndex = getHwComposer().getActiveConfigIndex(*displayId); - if (!isConfigAllowed(*displayId, currentConfigIndex)) { - for (const auto& [type, config] : mRefreshRateConfigs[*displayId]->getRefreshRates()) { - if (config && isConfigAllowed(*displayId, config->configId)) { - // TODO: we switch to the first allowed config. In the future - // we may want to enhance this logic to pick a similar config - // to the current one - ALOGV("Old config is not allowed - switching to config %d", config->configId); - setDesiredActiveConfig(displayToken, config->configId, - Scheduler::ConfigEvent::Changed); - break; - } - } - } - - // If idle timer and fps detection are disabled and we are in RefreshRateType::DEFAULT, - // there is no trigger to move to RefreshRateType::PERFORMANCE, even if it is an allowed. - if (!mScheduler->isIdleTimerEnabled() && !mUseSmart90ForVideo) { - const auto& performanceRefreshRate = - mRefreshRateConfigs[*displayId]->getRefreshRate(RefreshRateType::PERFORMANCE); - if (performanceRefreshRate && - isConfigAllowed(*displayId, performanceRefreshRate->configId)) { - setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::Changed); + // Set the highest allowed config by iterating backwards on available refresh rates + const auto& refreshRates = mRefreshRateConfigs[*displayId]->getRefreshRates(); + for (auto iter = refreshRates.crbegin(); iter != refreshRates.crend(); ++iter) { + if (iter->second && isConfigAllowed(*displayId, iter->second->configId)) { + ALOGV("switching to config %d", iter->second->configId); + setDesiredActiveConfig({iter->first, iter->second->configId, displayToken, + Scheduler::ConfigEvent::Changed}); + break; } } } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 26d0cd1412..3d8b6b791a 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -90,6 +90,8 @@ using namespace android::surfaceflinger; namespace android { +using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; + // --------------------------------------------------------------------------- class Client; @@ -102,6 +104,7 @@ class IGraphicBufferProducer; class IInputFlinger; class InjectVSyncSource; class Layer; +class RefreshRateOverlay; class Surface; class SurfaceFlingerBE; class TimeStats; @@ -366,6 +369,7 @@ private: friend class BufferQueueLayer; friend class BufferStateLayer; friend class MonitoredProducer; + friend class RefreshRateOverlay; friend class RegionSamplingThread; friend class SurfaceTracing; @@ -431,8 +435,8 @@ private: const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, - int64_t desiredPresentTime, - const cached_buffer_t& uncacheBuffer) override; + int64_t desiredPresentTime, const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks) override; void bootFinished() override; bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const override; @@ -528,11 +532,30 @@ private: void signalLayerUpdate(); void signalRefresh(); + struct ActiveConfigInfo { + RefreshRateType type; + int configId; + sp<IBinder> displayToken; + Scheduler::ConfigEvent event; + + bool operator!=(const ActiveConfigInfo& other) const { + if (type != other.type) { + return true; + } + if (configId != other.configId) { + return true; + } + if (displayToken != other.displayToken) { + return true; + } + return (event != other.event); + } + }; + // called on the main thread in response to initializeDisplays() void onInitializeDisplays() REQUIRES(mStateLock); // Sets the desired active config bit. It obtains the lock, and sets mDesiredActiveConfig. - void setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, - Scheduler::ConfigEvent event) REQUIRES(mStateLock); + void setDesiredActiveConfig(const ActiveConfigInfo& info) REQUIRES(mStateLock); // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. It also triggers HWC vsync. void setActiveConfigInternal() REQUIRES(mStateLock); @@ -579,8 +602,10 @@ private: const Vector<DisplayState>& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, - const cached_buffer_t& uncacheBuffer, const int64_t postTime, - bool privileged, bool isMainThread = false) REQUIRES(mStateLock); + const cached_buffer_t& uncacheBuffer, + const std::vector<ListenerCallbacks>& listenerCallbacks, + const int64_t postTime, bool privileged, bool isMainThread = false) + REQUIRES(mStateLock); bool flushTransactionQueues(); uint32_t getTransactionFlags(uint32_t flags); uint32_t peekTransactionFlags(); @@ -593,6 +618,7 @@ private: bool transactionIsReadyToBeApplied(int64_t desiredPresentTime, const Vector<ComposerState>& states); uint32_t setClientStateLocked(const ComposerState& composerState, int64_t desiredPresentTime, + const std::vector<ListenerCallbacks>& listenerCallbacks, int64_t postTime, bool privileged) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) @@ -815,8 +841,7 @@ private: // Sets the refresh rate by switching active configs, if they are available for // the desired refresh rate. - void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType, - Scheduler::ConfigEvent event) REQUIRES(mStateLock); + void setRefreshRateTo(RefreshRateType, Scheduler::ConfigEvent event) REQUIRES(mStateLock); bool isConfigAllowed(const DisplayId& displayId, int32_t config); @@ -938,6 +963,7 @@ private: bool mTransactionPending; bool mAnimTransactionPending; SortedVector< sp<Layer> > mLayersPendingRemoval; + bool mTraversalNeededMainThread; // guards access to the mDrawing state if tracing is enabled. mutable std::mutex mDrawingStateLock; @@ -1062,12 +1088,14 @@ private: TransactionState(const Vector<ComposerState>& composerStates, const Vector<DisplayState>& displayStates, uint32_t transactionFlags, int64_t desiredPresentTime, const cached_buffer_t& uncacheBuffer, - int64_t postTime, bool privileged) + const std::vector<ListenerCallbacks>& listenerCallbacks, int64_t postTime, + bool privileged) : states(composerStates), displays(displayStates), flags(transactionFlags), desiredPresentTime(desiredPresentTime), buffer(uncacheBuffer), + callback(listenerCallbacks), postTime(postTime), privileged(privileged) {} @@ -1076,6 +1104,7 @@ private: uint32_t flags; const int64_t desiredPresentTime; cached_buffer_t buffer; + std::vector<ListenerCallbacks> callback; const int64_t postTime; bool privileged; }; @@ -1134,18 +1163,6 @@ private: std::unordered_map<DisplayId, std::unique_ptr<const AllowedDisplayConfigs>> mAllowedConfigs GUARDED_BY(mAllowedConfigsLock); - struct ActiveConfigInfo { - int configId; - sp<IBinder> displayToken; - Scheduler::ConfigEvent event; - - bool operator!=(const ActiveConfigInfo& other) const { - if (configId != other.configId) { - return true; - } - return (displayToken != other.displayToken); - } - }; std::mutex mActiveConfigLock; // This bit is set once we start setting the config. We read from this bit during the // process. If at the end, this bit is different than mDesiredActiveConfig, we restart @@ -1172,6 +1189,8 @@ private: sp<SetInputWindowsListener> mSetInputWindowsListener; bool mPendingSyncInputWindows GUARDED_BY(mStateLock); Hwc2::impl::PowerAdvisor mPowerAdvisor; + + std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay; }; }; // namespace android diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp index e130511e94..09b793a035 100644 --- a/services/surfaceflinger/SurfaceFlingerProperties.cpp +++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp @@ -1,6 +1,4 @@ -#include <sysprop/SurfaceFlingerProperties.sysprop.h> - #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h> #include <android/hardware/configstore/1.1/types.h> diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h index 6f90117458..b2fafddfe7 100644 --- a/services/surfaceflinger/SurfaceFlingerProperties.h +++ b/services/surfaceflinger/SurfaceFlingerProperties.h @@ -2,9 +2,9 @@ #ifndef SURFACEFLINGERPROPERTIES_H_ #define SURFACEFLINGERPROPERTIES_H_ +#include <SurfaceFlingerProperties.sysprop.h> #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h> #include <android/hardware/graphics/common/1.2/types.h> -#include <sysprop/SurfaceFlingerProperties.sysprop.h> #include <ui/ConfigStoreTypes.h> #include <cstdint> diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp index d2b7fe099f..6e0c1e2d97 100644 --- a/services/surfaceflinger/TransactionCompletedThread.cpp +++ b/services/surfaceflinger/TransactionCompletedThread.cpp @@ -100,26 +100,48 @@ void TransactionCompletedThread::addUnpresentedCallbackHandle(const sp<CallbackH addCallbackHandle(handle); } -void TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>& handle) { +void TransactionCompletedThread::addCallback( + const sp<ITransactionCompletedListener>& transactionListener, + const std::vector<CallbackId>& callbackIds) { + std::lock_guard lock(mMutex); + addCallbackLocked(transactionListener, callbackIds); +} + +status_t TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>& handle) { + status_t err = addCallbackLocked(handle->listener, handle->callbackIds); + if (err != NO_ERROR) { + ALOGE("cannot add callback, err: %d", err); + return err; + } + const sp<IBinder> listener = IInterface::asBinder(handle->listener); + auto& listenerStats = mListenerStats[listener]; + auto& transactionStats = listenerStats.transactionStats[handle->callbackIds]; + transactionStats.latchTime = handle->latchTime; + transactionStats.surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime, + handle->previousReleaseFence); + return NO_ERROR; +} + +status_t TransactionCompletedThread::addCallbackLocked( + const sp<ITransactionCompletedListener>& transactionListener, + const std::vector<CallbackId>& callbackIds) { + const sp<IBinder> listener = IInterface::asBinder(transactionListener); // If we don't already have a reference to this listener, linkToDeath so we get a notification // if it dies. if (mListenerStats.count(listener) == 0) { - status_t error = listener->linkToDeath(mDeathRecipient); - if (error != NO_ERROR) { - ALOGE("cannot add callback handle because linkToDeath failed, err: %d", error); - return; + status_t err = listener->linkToDeath(mDeathRecipient); + if (err != NO_ERROR) { + ALOGE("cannot add callback because linkToDeath failed, err: %d", err); + return err; } } auto& listenerStats = mListenerStats[listener]; - listenerStats.listener = handle->listener; - - auto& transactionStats = listenerStats.transactionStats[handle->callbackIds]; - transactionStats.latchTime = handle->latchTime; - transactionStats.surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime, - handle->previousReleaseFence); + listenerStats.listener = transactionListener; + listenerStats.transactionStats[callbackIds]; + return NO_ERROR; } void TransactionCompletedThread::addPresentFence(const sp<Fence>& presentFence) { diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h index f49306d70e..88808fd0da 100644 --- a/services/surfaceflinger/TransactionCompletedThread.h +++ b/services/surfaceflinger/TransactionCompletedThread.h @@ -64,6 +64,11 @@ public: // presented this frame. void addUnpresentedCallbackHandle(const sp<CallbackHandle>& handle); + // Adds listener and callbackIds in case there are no SurfaceControls that are supposed + // to be included in the callback. + void addCallback(const sp<ITransactionCompletedListener>& transactionListener, + const std::vector<CallbackId>& callbackIds); + void addPresentFence(const sp<Fence>& presentFence); void sendCallbacks(); @@ -71,7 +76,9 @@ public: private: void threadMain(); - void addCallbackHandle(const sp<CallbackHandle>& handle) REQUIRES(mMutex); + status_t addCallbackHandle(const sp<CallbackHandle>& handle) REQUIRES(mMutex); + status_t addCallbackLocked(const sp<ITransactionCompletedListener>& transactionListener, + const std::vector<CallbackId>& callbackIds) REQUIRES(mMutex); class ThreadDeathRecipient : public IBinder::DeathRecipient { public: diff --git a/services/surfaceflinger/sysprop/Android.bp b/services/surfaceflinger/sysprop/Android.bp new file mode 100644 index 0000000000..7721d7d2b7 --- /dev/null +++ b/services/surfaceflinger/sysprop/Android.bp @@ -0,0 +1,6 @@ +sysprop_library { + name: "SurfaceFlingerProperties", + srcs: ["*.sysprop"], + api_packages: ["android.sysprop"], + property_owner: "Platform", +} diff --git a/services/surfaceflinger/sysprop/api/current.txt b/services/surfaceflinger/sysprop/api/current.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/sysprop/api/removed.txt b/services/surfaceflinger/sysprop/api/removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/sysprop/api/system-current.txt b/services/surfaceflinger/sysprop/api/system-current.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/system-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/sysprop/api/system-removed.txt b/services/surfaceflinger/sysprop/api/system-removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/system-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/sysprop/api/test-current.txt b/services/surfaceflinger/sysprop/api/test-current.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/test-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/sysprop/api/test-removed.txt b/services/surfaceflinger/sysprop/api/test-removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/services/surfaceflinger/sysprop/api/test-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index 406ec81ce4..249c78f09c 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -38,6 +38,7 @@ namespace { constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = 111; constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = 222; +constexpr PhysicalDisplayId DISPLAY_ID_64BIT = 0xabcd12349876fedcULL; class MockVSyncSource : public VSyncSource { public: @@ -470,5 +471,10 @@ TEST_F(EventThreadTest, postConfigChangedExternal) { expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5); } +TEST_F(EventThreadTest, postConfigChangedPrimary64bit) { + mThread->onConfigChanged(DISPLAY_ID_64BIT, 7); + expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7); +} + } // namespace } // namespace android diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp index 4e24a64691..afb30043ef 100644 --- a/services/vr/bufferhubd/Android.bp +++ b/services/vr/bufferhubd/Android.bp @@ -44,9 +44,6 @@ cc_library_static { static_libs: [ "libbufferhub", ], - - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } cc_binary { diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp index 206c8eb379..71a120a896 100644 --- a/vulkan/libvulkan/Android.bp +++ b/vulkan/libvulkan/Android.bp @@ -76,6 +76,7 @@ cc_library_shared { "libhardware", "libsync", "libbase", + "libdl_android", "libhidlbase", "libhidltransport", "liblog", |