Merge "Switch media fw permissions checks to AttributionSource (native)" into sc-dev
diff --git a/aidl/gui/android/view/LayerMetadataKey.aidl b/aidl/gui/android/view/LayerMetadataKey.aidl
index a1d8ce5..d6ca3db 100644
--- a/aidl/gui/android/view/LayerMetadataKey.aidl
+++ b/aidl/gui/android/view/LayerMetadataKey.aidl
@@ -26,4 +26,5 @@
     METADATA_ACCESSIBILITY_ID = 5,
     METADATA_OWNER_PID = 6,
     METADATA_DEQUEUE_TIME = 7,
+    METADATA_GAME_MODE = 8,
 }
diff --git a/libs/gui/LayerMetadata.cpp b/libs/gui/LayerMetadata.cpp
index 634d8b7..189d51a 100644
--- a/libs/gui/LayerMetadata.cpp
+++ b/libs/gui/LayerMetadata.cpp
@@ -136,6 +136,8 @@
             return StringPrintf("ownerPID%s%d", separator, getInt32(key, 0));
         case view::LayerMetadataKey::METADATA_DEQUEUE_TIME:
             return StringPrintf("dequeueTime%s%" PRId64, separator, *getInt64(key));
+        case view::LayerMetadataKey::METADATA_GAME_MODE:
+            return StringPrintf("gameMode%s%d", separator, getInt32(key, 0));
         default:
             return StringPrintf("%d%s%dbytes", key, separator,
                                 static_cast<int>(mMap.at(key).size()));
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 41982c2..de14b3d 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -29,7 +29,8 @@
     METADATA_MOUSE_CURSOR = 4,
     METADATA_ACCESSIBILITY_ID = 5,
     METADATA_OWNER_PID = 6,
-    METADATA_DEQUEUE_TIME = 7
+    METADATA_DEQUEUE_TIME = 7,
+    METADATA_GAME_MODE = 8
 };
 
 struct LayerMetadata : public Parcelable {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 7e069c8..cf433c0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3893,12 +3893,6 @@
                                               args->xCursorPosition, args->yCursorPosition,
                                               args->downTime, args->pointerCount,
                                               args->pointerProperties, args->pointerCoords, 0, 0);
-        if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
-            IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
-            !mInputFilterEnabled) {
-            const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
-            mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
-        }
 
         needWake = enqueueInboundEventLocked(std::move(newEntry));
         mLock.unlock();
diff --git a/services/surfaceflinger/EffectLayer.cpp b/services/surfaceflinger/EffectLayer.cpp
index fd18c3b..0cc5f33 100644
--- a/services/surfaceflinger/EffectLayer.cpp
+++ b/services/surfaceflinger/EffectLayer.cpp
@@ -66,6 +66,7 @@
         layerSettings->source.solidColor = getColor().rgb;
         results.push_back(*layerSettings);
     } else if (hasBlur() || drawShadows()) {
+        layerSettings->skipContentDraw = true;
         results.push_back(*layerSettings);
     }
 
@@ -126,7 +127,7 @@
 bool EffectLayer::isOpaque(const Layer::State& s) const {
     // Consider the layer to be opaque if its opaque flag is set or its effective
     // alpha (considering the alpha of its parents as well) is 1.0;
-    return (s.flags & layer_state_t::eLayerOpaque) != 0 || getAlpha() == 1.0_hf;
+    return (s.flags & layer_state_t::eLayerOpaque) != 0 || (fillsColor() && getAlpha() == 1.0_hf);
 }
 
 ui::Dataspace EffectLayer::getDataSpace() const {
@@ -147,7 +148,7 @@
 }
 
 bool EffectLayer::hasBlur() const {
-    return getBackgroundBlurRadius() > 0;
+    return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0;
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index f19e2a7..9b03287 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -136,6 +136,10 @@
         janks.emplace_back("Unknown jank");
         jankType &= ~JankType::Unknown;
     }
+    if (jankType & JankType::SurfaceFlingerStuffing) {
+        janks.emplace_back("SurfaceFlinger Stuffing");
+        jankType &= ~JankType::SurfaceFlingerStuffing;
+    }
 
     // jankType should be 0 if all types of jank were checked for.
     LOG_ALWAYS_FATAL_IF(jankType != 0, "Unrecognized jank type value 0x%x", jankType);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a7c8704..d720bcb 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -574,7 +574,8 @@
     layerSettings.geometry.positionTransform = getTransform().asMatrix4();
 
     // skip drawing content if the targetSettings indicate the content will be occluded
-    layerSettings.skipContentDraw = !targetSettings.realContentIsVisible;
+    layerSettings.skipContentDraw =
+            layerSettings.skipContentDraw || !targetSettings.realContentIsVisible;
 
     if (hasColorTransform()) {
         layerSettings.colorTransform = getColorTransform();
@@ -1651,12 +1652,25 @@
     return count;
 }
 
+void Layer::setGameModeForTree(int parentGameMode) {
+    int gameMode = parentGameMode;
+    auto& currentState = getCurrentState();
+    if (currentState.metadata.has(METADATA_GAME_MODE)) {
+        gameMode = currentState.metadata.getInt32(METADATA_GAME_MODE, 0);
+    }
+    setGameMode(gameMode);
+    for (const sp<Layer>& child : mCurrentChildren) {
+        child->setGameModeForTree(gameMode);
+    }
+}
+
 void Layer::addChild(const sp<Layer>& layer) {
     mChildrenChanged = true;
     setTransactionFlags(eTransactionNeeded);
 
     mCurrentChildren.add(layer);
     layer->setParent(this);
+    layer->setGameModeForTree(mGameMode);
     updateTreeHasFrameRateVote();
 }
 
@@ -1668,6 +1682,7 @@
     const auto removeResult = mCurrentChildren.remove(layer);
 
     updateTreeHasFrameRateVote();
+    layer->setGameModeForTree(0);
     layer->updateTreeHasFrameRateVote();
 
     return removeResult;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 66d7018..af26045 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -847,6 +847,13 @@
      */
     bool hasInputInfo() const;
 
+    // Sets the parent's gameMode for this layer and all its children. Parent's gameMode is applied
+    // only to layers that do not have the GAME_MODE_METADATA set by WMShell. Any layer(along with
+    // its children) that has the metadata set will use the gameMode from the metadata.
+    void setGameModeForTree(int parentGameMode);
+    void setGameMode(int gameMode) { mGameMode = gameMode; };
+    int getGameMode() const { return mGameMode; }
+
     virtual uid_t getOwnerUid() const { return mOwnerUid; }
 
     pid_t getOwnerPid() { return mOwnerPid; }
@@ -1089,6 +1096,10 @@
     // shadow radius is the set shadow radius, otherwise its the parent's shadow radius.
     float mEffectiveShadowRadius = 0.f;
 
+    // Game mode for the layer. Set by WindowManagerShell, game mode is used in
+    // metrics(SurfaceFlingerStats).
+    int mGameMode = 0;
+
     // A list of regions on this layer that should have blurs.
     const std::vector<BlurRegion> getBlurRegions() const;
 };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 881ee5b..a86e061 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -789,11 +789,6 @@
 
     property_get("persist.sys.sf.color_mode", value, "0");
     mForceColorMode = static_cast<ColorMode>(atoi(value));
-
-    property_get("persist.sys.sf.disable_blurs", value, "0");
-    bool disableBlurs = atoi(value);
-    mDisableBlurs = disableBlurs;
-    ALOGI_IF(disableBlurs, "Disabling blur effects, user preference.");
 }
 
 void SurfaceFlinger::startBootAnim() {
@@ -3953,7 +3948,7 @@
         if (layer->setCornerRadius(s.cornerRadius))
             flags |= eTraversalNeeded;
     }
-    if (what & layer_state_t::eBackgroundBlurRadiusChanged && !mDisableBlurs && mSupportsBlur) {
+    if (what & layer_state_t::eBackgroundBlurRadiusChanged && mSupportsBlur) {
         if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eBlurRegionsChanged) {
@@ -4018,6 +4013,13 @@
     std::optional<nsecs_t> dequeueBufferTimestamp;
     if (what & layer_state_t::eMetadataChanged) {
         dequeueBufferTimestamp = s.metadata.getInt64(METADATA_DEQUEUE_TIME);
+        auto gameMode = s.metadata.getInt32(METADATA_GAME_MODE, -1);
+        if (gameMode != -1) {
+            // The transaction will be received on the Task layer and needs to be applied to all
+            // child layers. Child layers that are added at a later point will obtain the game mode
+            // info through addChild().
+            layer->setGameModeForTree(gameMode);
+        }
         if (layer->setMetadata(s.metadata)) flags |= eTraversalNeeded;
     }
     if (what & layer_state_t::eColorSpaceAgnosticChanged) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c382005..30d76af 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1264,8 +1264,6 @@
     bool mUseHwcVirtualDisplays = false;
     // If blurs should be enabled on this device.
     bool mSupportsBlur = false;
-    // Disable blurs, for debugging
-    std::atomic<bool> mDisableBlurs = false;
     // If blurs are considered expensive and should require high GPU frequency.
     bool mBlursAreExpensive = false;
     std::atomic<uint32_t> mFrameMissedCount = 0;
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 1b25a36..736ef30 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -57,6 +57,7 @@
         "FpsTest.cpp",
         "FramebufferSurfaceTest.cpp",
         "FrameTimelineTest.cpp",
+        "GameModeTest.cpp",
         "HWComposerTest.cpp",
         "OneShotTimerTest.cpp",
         "LayerHistoryTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/GameModeTest.cpp b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
new file mode 100644
index 0000000..3fa1a2c
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "LibSurfaceFlingerUnittests"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <gui/LayerMetadata.h>
+#include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
+
+#include "TestableSurfaceFlinger.h"
+#include "mock/DisplayHardware/MockComposer.h"
+#include "mock/MockEventThread.h"
+#include "mock/MockVsyncController.h"
+
+namespace android {
+
+using testing::_;
+using testing::Mock;
+using testing::Return;
+using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
+
+class GameModeTest : public testing::Test {
+public:
+    GameModeTest() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+        setupScheduler();
+        setupComposer();
+    }
+
+    ~GameModeTest() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
+    }
+
+    sp<BufferStateLayer> createBufferStateLayer() {
+        sp<Client> client;
+        LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 100, 100, 0,
+                               LayerMetadata());
+        return new BufferStateLayer(args);
+    }
+
+    void setupScheduler() {
+        auto eventThread = std::make_unique<mock::EventThread>();
+        auto sfEventThread = std::make_unique<mock::EventThread>();
+
+        EXPECT_CALL(*eventThread, registerDisplayEventConnection(_));
+        EXPECT_CALL(*eventThread, createEventConnection(_, _))
+                .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0,
+                                                           ResyncCallback())));
+
+        EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_));
+        EXPECT_CALL(*sfEventThread, createEventConnection(_, _))
+                .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0,
+                                                           ResyncCallback())));
+
+        auto vsyncController = std::make_unique<mock::VsyncController>();
+        auto vsyncTracker = std::make_unique<mock::VSyncTracker>();
+
+        EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+        EXPECT_CALL(*vsyncTracker, currentPeriod())
+                .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
+        EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+        mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker),
+                                std::move(eventThread), std::move(sfEventThread));
+    }
+
+    void setupComposer() {
+        mComposer = new Hwc2::mock::Composer();
+        mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
+
+        Mock::VerifyAndClear(mComposer);
+    }
+
+    // Mocks the behavior of applying a transaction from WMShell
+    void setGameModeMetadata(sp<Layer> layer, int gameMode) {
+        mLayerMetadata.setInt32(METADATA_GAME_MODE, gameMode);
+        layer->setMetadata(mLayerMetadata);
+        layer->setGameModeForTree(gameMode);
+    }
+
+    TestableSurfaceFlinger mFlinger;
+    Hwc2::mock::Composer* mComposer = nullptr;
+    client_cache_t mClientCache;
+    LayerMetadata mLayerMetadata;
+};
+
+TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) {
+    sp<BufferStateLayer> rootLayer = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
+    rootLayer->addChild(childLayer1);
+    rootLayer->addChild(childLayer2);
+    rootLayer->setGameModeForTree(/*gameMode*/ 2);
+
+    EXPECT_EQ(rootLayer->getGameMode(), 2);
+    EXPECT_EQ(childLayer1->getGameMode(), 2);
+    EXPECT_EQ(childLayer2->getGameMode(), 2);
+}
+
+TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) {
+    sp<BufferStateLayer> rootLayer = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer = createBufferStateLayer();
+    rootLayer->setGameModeForTree(/*gameMode*/ 2);
+    rootLayer->addChild(childLayer);
+
+    EXPECT_EQ(rootLayer->getGameMode(), 2);
+    EXPECT_EQ(childLayer->getGameMode(), 2);
+}
+
+TEST_F(GameModeTest, RemoveChildResetsGameMode) {
+    sp<BufferStateLayer> rootLayer = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer = createBufferStateLayer();
+    rootLayer->setGameModeForTree(/*gameMode*/ 2);
+    rootLayer->addChild(childLayer);
+
+    EXPECT_EQ(rootLayer->getGameMode(), 2);
+    EXPECT_EQ(childLayer->getGameMode(), 2);
+
+    rootLayer->removeChild(childLayer);
+    EXPECT_EQ(childLayer->getGameMode(), 0);
+}
+
+TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) {
+    sp<BufferStateLayer> rootLayer = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
+    sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
+    rootLayer->setGameModeForTree(/*gameMode*/ 1);
+    rootLayer->addChild(childLayer1);
+
+    setGameModeMetadata(childLayer2, /*gameMode*/ 2);
+    rootLayer->addChild(childLayer2);
+
+    EXPECT_EQ(rootLayer->getGameMode(), 1);
+    EXPECT_EQ(childLayer1->getGameMode(), 1);
+    EXPECT_EQ(childLayer2->getGameMode(), 2);
+
+    rootLayer->removeChild(childLayer2);
+    EXPECT_EQ(childLayer2->getGameMode(), 2);
+}
+} // namespace android
\ No newline at end of file